1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * vsp1_drv.c -- R-Car VSP1 Driver 4 * 5 * Copyright (C) 2013-2015 Renesas Electronics Corporation 6 * 7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/device.h> 13 #include <linux/interrupt.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/reset.h> 19 #include <linux/videodev2.h> 20 21 #include <media/rcar-fcp.h> 22 #include <media/v4l2-subdev.h> 23 24 #include "vsp1.h" 25 #include "vsp1_brx.h" 26 #include "vsp1_clu.h" 27 #include "vsp1_dl.h" 28 #include "vsp1_drm.h" 29 #include "vsp1_hgo.h" 30 #include "vsp1_hgt.h" 31 #include "vsp1_hsit.h" 32 #include "vsp1_iif.h" 33 #include "vsp1_lif.h" 34 #include "vsp1_lut.h" 35 #include "vsp1_pipe.h" 36 #include "vsp1_regs.h" 37 #include "vsp1_rwpf.h" 38 #include "vsp1_sru.h" 39 #include "vsp1_uds.h" 40 #include "vsp1_uif.h" 41 #include "vsp1_video.h" 42 #include "vsp1_vspx.h" 43 44 /* ----------------------------------------------------------------------------- 45 * Interrupt Handling 46 */ 47 48 static irqreturn_t vsp1_irq_handler(int irq, void *data) 49 { 50 u32 mask = VI6_WPF_IRQ_STA_DFE | VI6_WPF_IRQ_STA_FRE | 51 VI6_WPF_IRQ_STA_UND; 52 struct vsp1_device *vsp1 = data; 53 irqreturn_t ret = IRQ_NONE; 54 unsigned int i; 55 u32 status; 56 57 for (i = 0; i < vsp1->info->wpf_count; ++i) { 58 struct vsp1_rwpf *wpf = vsp1->wpf[i]; 59 60 if (wpf == NULL) 61 continue; 62 63 status = vsp1_read(vsp1, VI6_WPF_IRQ_STA(i)); 64 vsp1_write(vsp1, VI6_WPF_IRQ_STA(i), ~status & mask); 65 66 if ((status & VI6_WPF_IRQ_STA_UND) && wpf->entity.pipe) { 67 wpf->entity.pipe->underrun_count++; 68 69 dev_warn_ratelimited(vsp1->dev, 70 "Underrun occurred at WPF%u (total underruns %u)\n", 71 i, wpf->entity.pipe->underrun_count); 72 } 73 74 if (status & VI6_WPF_IRQ_STA_DFE) { 75 vsp1_pipeline_frame_end(wpf->entity.pipe); 76 ret = IRQ_HANDLED; 77 } 78 } 79 80 return ret; 81 } 82 83 /* ----------------------------------------------------------------------------- 84 * Entities 85 */ 86 87 /* 88 * vsp1_create_sink_links - Create links from all sources to the given sink 89 * 90 * This function creates media links from all valid sources to the given sink 91 * pad. Links that would be invalid according to the VSP1 hardware capabilities 92 * are skipped. Those include all links 93 * 94 * - from a UDS to a UDS (UDS entities can't be chained) 95 * - from an entity to itself (no loops are allowed) 96 * 97 * Furthermore, the BRS can't be connected to histogram generators, but no 98 * special check is currently needed as all VSP instances that include a BRS 99 * have no histogram generator. 100 */ 101 static int vsp1_create_sink_links(struct vsp1_device *vsp1, 102 struct vsp1_entity *sink) 103 { 104 struct media_entity *entity = &sink->subdev.entity; 105 struct vsp1_entity *source; 106 unsigned int pad; 107 int ret; 108 109 list_for_each_entry(source, &vsp1->entities, list_dev) { 110 u32 flags; 111 112 if (source->type == sink->type) 113 continue; 114 115 if (source->type == VSP1_ENTITY_HGO || 116 source->type == VSP1_ENTITY_HGT || 117 source->type == VSP1_ENTITY_LIF || 118 source->type == VSP1_ENTITY_WPF) 119 continue; 120 121 flags = source->type == VSP1_ENTITY_RPF && 122 sink->type == VSP1_ENTITY_WPF && 123 source->index == sink->index 124 ? MEDIA_LNK_FL_ENABLED : 0; 125 126 for (pad = 0; pad < entity->num_pads; ++pad) { 127 if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK)) 128 continue; 129 130 ret = media_create_pad_link(&source->subdev.entity, 131 source->source_pad, 132 entity, pad, flags); 133 if (ret < 0) 134 return ret; 135 136 if (flags & MEDIA_LNK_FL_ENABLED) 137 source->sink = sink; 138 } 139 } 140 141 return 0; 142 } 143 144 static int vsp1_uapi_create_links(struct vsp1_device *vsp1) 145 { 146 struct vsp1_entity *entity; 147 unsigned int i; 148 int ret; 149 150 list_for_each_entry(entity, &vsp1->entities, list_dev) { 151 if (entity->type == VSP1_ENTITY_LIF || 152 entity->type == VSP1_ENTITY_RPF) 153 continue; 154 155 ret = vsp1_create_sink_links(vsp1, entity); 156 if (ret < 0) 157 return ret; 158 } 159 160 if (vsp1->hgo) { 161 ret = media_create_pad_link(&vsp1->hgo->histo.entity.subdev.entity, 162 HISTO_PAD_SOURCE, 163 &vsp1->hgo->histo.video.entity, 0, 164 MEDIA_LNK_FL_ENABLED | 165 MEDIA_LNK_FL_IMMUTABLE); 166 if (ret < 0) 167 return ret; 168 } 169 170 if (vsp1->hgt) { 171 ret = media_create_pad_link(&vsp1->hgt->histo.entity.subdev.entity, 172 HISTO_PAD_SOURCE, 173 &vsp1->hgt->histo.video.entity, 0, 174 MEDIA_LNK_FL_ENABLED | 175 MEDIA_LNK_FL_IMMUTABLE); 176 if (ret < 0) 177 return ret; 178 } 179 180 for (i = 0; i < vsp1->info->lif_count; ++i) { 181 if (!vsp1->lif[i]) 182 continue; 183 184 ret = media_create_pad_link(&vsp1->wpf[i]->entity.subdev.entity, 185 RWPF_PAD_SOURCE, 186 &vsp1->lif[i]->entity.subdev.entity, 187 LIF_PAD_SINK, 0); 188 if (ret < 0) 189 return ret; 190 } 191 192 for (i = 0; i < vsp1->info->rpf_count; ++i) { 193 struct vsp1_rwpf *rpf = vsp1->rpf[i]; 194 195 ret = media_create_pad_link(&rpf->video->video.entity, 0, 196 &rpf->entity.subdev.entity, 197 RWPF_PAD_SINK, 198 MEDIA_LNK_FL_ENABLED | 199 MEDIA_LNK_FL_IMMUTABLE); 200 if (ret < 0) 201 return ret; 202 } 203 204 for (i = 0; i < vsp1->info->wpf_count; ++i) { 205 /* 206 * Connect the video device to the WPF. All connections are 207 * immutable. 208 */ 209 struct vsp1_rwpf *wpf = vsp1->wpf[i]; 210 211 ret = media_create_pad_link(&wpf->entity.subdev.entity, 212 RWPF_PAD_SOURCE, 213 &wpf->video->video.entity, 0, 214 MEDIA_LNK_FL_IMMUTABLE | 215 MEDIA_LNK_FL_ENABLED); 216 if (ret < 0) 217 return ret; 218 } 219 220 return 0; 221 } 222 223 static void vsp1_destroy_entities(struct vsp1_device *vsp1) 224 { 225 struct vsp1_entity *entity, *_entity; 226 struct vsp1_video *video, *_video; 227 228 list_for_each_entry_safe(entity, _entity, &vsp1->entities, list_dev) { 229 list_del(&entity->list_dev); 230 vsp1_entity_destroy(entity); 231 } 232 233 list_for_each_entry_safe(video, _video, &vsp1->videos, list) { 234 list_del(&video->list); 235 vsp1_video_cleanup(video); 236 } 237 238 v4l2_device_unregister(&vsp1->v4l2_dev); 239 if (vsp1->info->uapi) 240 media_device_unregister(&vsp1->media_dev); 241 media_device_cleanup(&vsp1->media_dev); 242 243 if (!vsp1->info->uapi) 244 vsp1_drm_cleanup(vsp1); 245 } 246 247 static int vsp1_create_entities(struct vsp1_device *vsp1) 248 { 249 struct media_device *mdev = &vsp1->media_dev; 250 struct v4l2_device *vdev = &vsp1->v4l2_dev; 251 struct vsp1_entity *entity; 252 unsigned int i; 253 int ret; 254 255 mdev->dev = vsp1->dev; 256 mdev->hw_revision = vsp1->version; 257 strscpy(mdev->model, vsp1->info->model, sizeof(mdev->model)); 258 media_device_init(mdev); 259 260 vsp1->media_ops.link_setup = vsp1_entity_link_setup; 261 /* 262 * Don't perform link validation when the userspace API is disabled as 263 * the pipeline is configured internally by the driver in that case, and 264 * its configuration can thus be trusted. 265 */ 266 if (vsp1->info->uapi) 267 vsp1->media_ops.link_validate = v4l2_subdev_link_validate; 268 269 vdev->mdev = mdev; 270 ret = v4l2_device_register(vsp1->dev, vdev); 271 if (ret < 0) { 272 dev_err(vsp1->dev, "V4L2 device registration failed (%d)\n", 273 ret); 274 goto done; 275 } 276 277 /* Instantiate all the entities. */ 278 if (vsp1_feature(vsp1, VSP1_HAS_BRS)) { 279 vsp1->brs = vsp1_brx_create(vsp1, VSP1_ENTITY_BRS); 280 if (IS_ERR(vsp1->brs)) { 281 ret = PTR_ERR(vsp1->brs); 282 goto done; 283 } 284 285 list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities); 286 } 287 288 if (vsp1_feature(vsp1, VSP1_HAS_BRU)) { 289 vsp1->bru = vsp1_brx_create(vsp1, VSP1_ENTITY_BRU); 290 if (IS_ERR(vsp1->bru)) { 291 ret = PTR_ERR(vsp1->bru); 292 goto done; 293 } 294 295 list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities); 296 } 297 298 if (vsp1_feature(vsp1, VSP1_HAS_CLU)) { 299 vsp1->clu = vsp1_clu_create(vsp1); 300 if (IS_ERR(vsp1->clu)) { 301 ret = PTR_ERR(vsp1->clu); 302 goto done; 303 } 304 305 list_add_tail(&vsp1->clu->entity.list_dev, &vsp1->entities); 306 } 307 308 if (vsp1_feature(vsp1, VSP1_HAS_HGO) && vsp1->info->uapi) { 309 vsp1->hgo = vsp1_hgo_create(vsp1); 310 if (IS_ERR(vsp1->hgo)) { 311 ret = PTR_ERR(vsp1->hgo); 312 goto done; 313 } 314 315 list_add_tail(&vsp1->hgo->histo.entity.list_dev, 316 &vsp1->entities); 317 } 318 319 if (vsp1_feature(vsp1, VSP1_HAS_HGT) && vsp1->info->uapi) { 320 vsp1->hgt = vsp1_hgt_create(vsp1); 321 if (IS_ERR(vsp1->hgt)) { 322 ret = PTR_ERR(vsp1->hgt); 323 goto done; 324 } 325 326 list_add_tail(&vsp1->hgt->histo.entity.list_dev, 327 &vsp1->entities); 328 } 329 330 if (vsp1_feature(vsp1, VSP1_HAS_IIF)) { 331 vsp1->iif = vsp1_iif_create(vsp1); 332 if (IS_ERR(vsp1->iif)) { 333 ret = PTR_ERR(vsp1->iif); 334 goto done; 335 } 336 337 list_add_tail(&vsp1->iif->entity.list_dev, &vsp1->entities); 338 } 339 340 if (vsp1_feature(vsp1, VSP1_HAS_HSIT)) { 341 vsp1->hsi = vsp1_hsit_create(vsp1, true); 342 if (IS_ERR(vsp1->hsi)) { 343 ret = PTR_ERR(vsp1->hsi); 344 goto done; 345 } 346 347 list_add_tail(&vsp1->hsi->entity.list_dev, &vsp1->entities); 348 349 vsp1->hst = vsp1_hsit_create(vsp1, false); 350 if (IS_ERR(vsp1->hst)) { 351 ret = PTR_ERR(vsp1->hst); 352 goto done; 353 } 354 355 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities); 356 } 357 358 /* 359 * The LIFs are only supported when used in conjunction with the DU, in 360 * which case the userspace API is disabled. If the userspace API is 361 * enabled skip the LIFs, even when present. 362 */ 363 if (!vsp1->info->uapi) { 364 for (i = 0; i < vsp1->info->lif_count; ++i) { 365 struct vsp1_lif *lif; 366 367 lif = vsp1_lif_create(vsp1, i); 368 if (IS_ERR(lif)) { 369 ret = PTR_ERR(lif); 370 goto done; 371 } 372 373 vsp1->lif[i] = lif; 374 list_add_tail(&lif->entity.list_dev, &vsp1->entities); 375 } 376 } 377 378 if (vsp1_feature(vsp1, VSP1_HAS_LUT)) { 379 vsp1->lut = vsp1_lut_create(vsp1); 380 if (IS_ERR(vsp1->lut)) { 381 ret = PTR_ERR(vsp1->lut); 382 goto done; 383 } 384 385 list_add_tail(&vsp1->lut->entity.list_dev, &vsp1->entities); 386 } 387 388 for (i = 0; i < vsp1->info->rpf_count; ++i) { 389 struct vsp1_rwpf *rpf; 390 391 rpf = vsp1_rpf_create(vsp1, i); 392 if (IS_ERR(rpf)) { 393 ret = PTR_ERR(rpf); 394 goto done; 395 } 396 397 vsp1->rpf[i] = rpf; 398 list_add_tail(&rpf->entity.list_dev, &vsp1->entities); 399 400 if (vsp1->info->uapi) { 401 struct vsp1_video *video = vsp1_video_create(vsp1, rpf); 402 403 if (IS_ERR(video)) { 404 ret = PTR_ERR(video); 405 goto done; 406 } 407 408 list_add_tail(&video->list, &vsp1->videos); 409 } 410 } 411 412 if (vsp1_feature(vsp1, VSP1_HAS_SRU)) { 413 vsp1->sru = vsp1_sru_create(vsp1); 414 if (IS_ERR(vsp1->sru)) { 415 ret = PTR_ERR(vsp1->sru); 416 goto done; 417 } 418 419 list_add_tail(&vsp1->sru->entity.list_dev, &vsp1->entities); 420 } 421 422 for (i = 0; i < vsp1->info->uds_count; ++i) { 423 struct vsp1_uds *uds; 424 425 uds = vsp1_uds_create(vsp1, i); 426 if (IS_ERR(uds)) { 427 ret = PTR_ERR(uds); 428 goto done; 429 } 430 431 vsp1->uds[i] = uds; 432 list_add_tail(&uds->entity.list_dev, &vsp1->entities); 433 } 434 435 for (i = 0; i < vsp1->info->uif_count; ++i) { 436 struct vsp1_uif *uif; 437 438 uif = vsp1_uif_create(vsp1, i); 439 if (IS_ERR(uif)) { 440 ret = PTR_ERR(uif); 441 goto done; 442 } 443 444 vsp1->uif[i] = uif; 445 list_add_tail(&uif->entity.list_dev, &vsp1->entities); 446 } 447 448 for (i = 0; i < vsp1->info->wpf_count; ++i) { 449 struct vsp1_rwpf *wpf; 450 451 wpf = vsp1_wpf_create(vsp1, i); 452 if (IS_ERR(wpf)) { 453 ret = PTR_ERR(wpf); 454 goto done; 455 } 456 457 vsp1->wpf[i] = wpf; 458 list_add_tail(&wpf->entity.list_dev, &vsp1->entities); 459 460 if (vsp1->info->uapi) { 461 struct vsp1_video *video = vsp1_video_create(vsp1, wpf); 462 463 if (IS_ERR(video)) { 464 ret = PTR_ERR(video); 465 goto done; 466 } 467 468 list_add_tail(&video->list, &vsp1->videos); 469 } 470 } 471 472 /* Register all subdevs. */ 473 list_for_each_entry(entity, &vsp1->entities, list_dev) { 474 ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, 475 &entity->subdev); 476 if (ret < 0) 477 goto done; 478 } 479 480 /* 481 * Create links and register subdev nodes if the userspace API is 482 * enabled or initialize the DRM pipeline otherwise. 483 */ 484 if (vsp1->info->uapi) { 485 ret = vsp1_uapi_create_links(vsp1); 486 if (ret < 0) 487 goto done; 488 489 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); 490 if (ret < 0) 491 goto done; 492 493 ret = media_device_register(mdev); 494 } else { 495 if (vsp1->info->version == VI6_IP_VERSION_MODEL_VSPX_GEN4) 496 ret = vsp1_vspx_init(vsp1); 497 else 498 ret = vsp1_drm_init(vsp1); 499 } 500 501 done: 502 if (ret < 0) 503 vsp1_destroy_entities(vsp1); 504 505 return ret; 506 } 507 508 int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index) 509 { 510 u32 version = vsp1->version & VI6_IP_VERSION_MODEL_MASK; 511 unsigned int timeout; 512 int ret = 0; 513 u32 status; 514 515 status = vsp1_read(vsp1, VI6_STATUS); 516 if (!(status & VI6_STATUS_SYS_ACT(index))) 517 return 0; 518 519 vsp1_write(vsp1, VI6_SRESET, VI6_SRESET_SRTS(index)); 520 for (timeout = 10; timeout > 0; --timeout) { 521 status = vsp1_read(vsp1, VI6_STATUS); 522 if (!(status & VI6_STATUS_SYS_ACT(index))) 523 break; 524 525 usleep_range(1000, 2000); 526 } 527 528 if (!timeout) { 529 dev_err(vsp1->dev, "failed to reset wpf.%u\n", index); 530 return -ETIMEDOUT; 531 } 532 533 if (version == VI6_IP_VERSION_MODEL_VSPD_GEN3 || 534 version == VI6_IP_VERSION_MODEL_VSPD_GEN4) 535 ret = rcar_fcp_soft_reset(vsp1->fcp); 536 537 return ret; 538 } 539 540 static int vsp1_device_init(struct vsp1_device *vsp1) 541 { 542 unsigned int i; 543 int ret; 544 545 /* Reset any channel that might be running. */ 546 for (i = 0; i < vsp1->info->wpf_count; ++i) { 547 ret = vsp1_reset_wpf(vsp1, i); 548 if (ret < 0) 549 return ret; 550 } 551 552 vsp1_write(vsp1, VI6_CLK_DCSWT, (8 << VI6_CLK_DCSWT_CSTPW_SHIFT) | 553 (8 << VI6_CLK_DCSWT_CSTRW_SHIFT)); 554 555 for (i = 0; i < vsp1->info->rpf_count; ++i) 556 vsp1_write(vsp1, VI6_DPR_RPF_ROUTE(i), VI6_DPR_NODE_UNUSED); 557 558 for (i = 0; i < vsp1->info->uds_count; ++i) 559 vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED); 560 561 for (i = 0; i < vsp1->info->uif_count; ++i) 562 vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED); 563 564 vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED); 565 vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED); 566 vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED); 567 vsp1_write(vsp1, VI6_DPR_HST_ROUTE, VI6_DPR_NODE_UNUSED); 568 vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED); 569 vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED); 570 571 if (vsp1_feature(vsp1, VSP1_HAS_BRS)) 572 vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED); 573 574 vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) | 575 (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT)); 576 vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) | 577 (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT)); 578 579 vsp1_dlm_setup(vsp1); 580 581 return 0; 582 } 583 584 static void vsp1_mask_all_interrupts(struct vsp1_device *vsp1) 585 { 586 unsigned int i; 587 588 for (i = 0; i < vsp1->info->lif_count; ++i) 589 vsp1_write(vsp1, VI6_DISP_IRQ_ENB(i), 0); 590 for (i = 0; i < vsp1->info->wpf_count; ++i) 591 vsp1_write(vsp1, VI6_WPF_IRQ_ENB(i), 0); 592 } 593 594 /* 595 * vsp1_device_get - Acquire the VSP1 device 596 * 597 * Make sure the device is not suspended and initialize it if needed. 598 * 599 * Return 0 on success or a negative error code otherwise. 600 */ 601 int vsp1_device_get(struct vsp1_device *vsp1) 602 { 603 return pm_runtime_resume_and_get(vsp1->dev); 604 } 605 606 /* 607 * vsp1_device_put - Release the VSP1 device 608 * 609 * Decrement the VSP1 reference count and cleanup the device if the last 610 * reference is released. 611 */ 612 void vsp1_device_put(struct vsp1_device *vsp1) 613 { 614 pm_runtime_put_sync(vsp1->dev); 615 } 616 617 /* ----------------------------------------------------------------------------- 618 * Power Management 619 */ 620 621 static int __maybe_unused vsp1_pm_suspend(struct device *dev) 622 { 623 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 624 625 /* 626 * When used as part of a display pipeline, the VSP is stopped and 627 * restarted explicitly by the DU. 628 */ 629 if (!vsp1->drm) 630 vsp1_video_suspend(vsp1); 631 632 pm_runtime_force_suspend(vsp1->dev); 633 634 return 0; 635 } 636 637 static int __maybe_unused vsp1_pm_resume(struct device *dev) 638 { 639 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 640 641 pm_runtime_force_resume(vsp1->dev); 642 643 /* 644 * When used as part of a display pipeline, the VSP is stopped and 645 * restarted explicitly by the DU. 646 */ 647 if (!vsp1->drm) 648 vsp1_video_resume(vsp1); 649 650 return 0; 651 } 652 653 static int __maybe_unused vsp1_pm_runtime_suspend(struct device *dev) 654 { 655 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 656 657 rcar_fcp_disable(vsp1->fcp); 658 reset_control_assert(vsp1->rstc); 659 660 return 0; 661 } 662 663 static int __maybe_unused vsp1_pm_runtime_resume(struct device *dev) 664 { 665 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 666 int ret; 667 668 ret = reset_control_deassert(vsp1->rstc); 669 if (ret < 0) 670 return ret; 671 672 if (vsp1->info) { 673 /* 674 * On R-Car Gen2 and RZ/G1, vsp1 register access after deassert 675 * can cause lock-up. It is a special case and needs some delay 676 * to avoid this lock-up. 677 */ 678 if (vsp1->info->gen == 2) 679 udelay(1); 680 681 ret = vsp1_device_init(vsp1); 682 if (ret < 0) 683 goto done; 684 } 685 686 ret = rcar_fcp_enable(vsp1->fcp); 687 688 done: 689 if (ret < 0) 690 reset_control_assert(vsp1->rstc); 691 692 return ret; 693 } 694 695 static const struct dev_pm_ops vsp1_pm_ops = { 696 SET_SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume) 697 SET_RUNTIME_PM_OPS(vsp1_pm_runtime_suspend, vsp1_pm_runtime_resume, NULL) 698 }; 699 700 /* ----------------------------------------------------------------------------- 701 * Platform Driver 702 */ 703 704 static const struct vsp1_device_info vsp1_device_infos[] = { 705 { 706 .version = VI6_IP_VERSION_MODEL_VSPS_H2, 707 .model = "VSP1-S", 708 .gen = 2, 709 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO 710 | VSP1_HAS_HGT | VSP1_HAS_HSIT | VSP1_HAS_LUT 711 | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP, 712 .rpf_count = 5, 713 .uds_count = 3, 714 .wpf_count = 4, 715 .num_bru_inputs = 4, 716 .uapi = true, 717 }, { 718 .version = VI6_IP_VERSION_MODEL_VSPR_H2, 719 .model = "VSP1-R", 720 .gen = 2, 721 .features = VSP1_HAS_BRU | VSP1_HAS_HSIT | VSP1_HAS_SRU 722 | VSP1_HAS_WPF_VFLIP, 723 .rpf_count = 5, 724 .uds_count = 3, 725 .wpf_count = 4, 726 .num_bru_inputs = 4, 727 .uapi = true, 728 }, { 729 .version = VI6_IP_VERSION_MODEL_VSPD_GEN2, 730 .model = "VSP1-D", 731 .gen = 2, 732 .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_HSIT 733 | VSP1_HAS_LUT, 734 .lif_count = 1, 735 .rpf_count = 4, 736 .uds_count = 1, 737 .wpf_count = 1, 738 .num_bru_inputs = 4, 739 .uapi = true, 740 }, { 741 .version = VI6_IP_VERSION_MODEL_VSPS_M2, 742 .model = "VSP1-S", 743 .gen = 2, 744 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO 745 | VSP1_HAS_HGT | VSP1_HAS_HSIT | VSP1_HAS_LUT 746 | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP, 747 .rpf_count = 5, 748 .uds_count = 1, 749 .wpf_count = 4, 750 .num_bru_inputs = 4, 751 .uapi = true, 752 }, { 753 .version = VI6_IP_VERSION_MODEL_VSPS_V2H, 754 .model = "VSP1V-S", 755 .gen = 2, 756 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HSIT 757 | VSP1_HAS_LUT | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP, 758 .rpf_count = 4, 759 .uds_count = 1, 760 .wpf_count = 4, 761 .num_bru_inputs = 4, 762 .uapi = true, 763 }, { 764 .version = VI6_IP_VERSION_MODEL_VSPD_V2H, 765 .model = "VSP1V-D", 766 .gen = 2, 767 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HSIT 768 | VSP1_HAS_LUT, 769 .lif_count = 1, 770 .rpf_count = 4, 771 .uds_count = 1, 772 .wpf_count = 1, 773 .num_bru_inputs = 4, 774 .uapi = true, 775 }, { 776 .version = VI6_IP_VERSION_MODEL_VSPI_GEN3, 777 .model = "VSP2-I", 778 .gen = 3, 779 .features = VSP1_HAS_CLU | VSP1_HAS_HGO | VSP1_HAS_HGT 780 | VSP1_HAS_HSIT | VSP1_HAS_LUT | VSP1_HAS_SRU 781 | VSP1_HAS_WPF_HFLIP | VSP1_HAS_WPF_VFLIP, 782 .rpf_count = 1, 783 .uds_count = 1, 784 .wpf_count = 1, 785 .uapi = true, 786 }, { 787 .version = VI6_IP_VERSION_MODEL_VSPBD_GEN3, 788 .model = "VSP2-BD", 789 .gen = 3, 790 .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP, 791 .rpf_count = 5, 792 .wpf_count = 1, 793 .num_bru_inputs = 5, 794 .uapi = true, 795 }, { 796 .version = VI6_IP_VERSION_MODEL_VSPBC_GEN3, 797 .model = "VSP2-BC", 798 .gen = 3, 799 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO 800 | VSP1_HAS_LUT | VSP1_HAS_WPF_VFLIP, 801 .rpf_count = 5, 802 .wpf_count = 1, 803 .num_bru_inputs = 5, 804 .uapi = true, 805 }, { 806 .version = VI6_IP_VERSION_MODEL_VSPBS_GEN3, 807 .model = "VSP2-BS", 808 .gen = 3, 809 .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP, 810 .rpf_count = 2, 811 .wpf_count = 1, 812 .uapi = true, 813 }, { 814 .version = VI6_IP_VERSION_MODEL_VSPD_GEN3, 815 .model = "VSP2-D", 816 .gen = 3, 817 .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL, 818 .lif_count = 1, 819 .rpf_count = 5, 820 .uif_count = 1, 821 .wpf_count = 2, 822 .num_bru_inputs = 5, 823 }, { 824 .version = VI6_IP_VERSION_MODEL_VSPD_V3, 825 .model = "VSP2-D", 826 .soc = VI6_IP_VERSION_SOC_V3H, 827 .gen = 3, 828 .features = VSP1_HAS_BRS | VSP1_HAS_BRU, 829 .lif_count = 1, 830 .rpf_count = 5, 831 .uif_count = 1, 832 .wpf_count = 1, 833 .num_bru_inputs = 5, 834 }, { 835 .version = VI6_IP_VERSION_MODEL_VSPD_V3, 836 .model = "VSP2-D", 837 .soc = VI6_IP_VERSION_SOC_V3M, 838 .gen = 3, 839 .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_NON_ZERO_LBA, 840 .lif_count = 1, 841 .rpf_count = 5, 842 .uif_count = 1, 843 .wpf_count = 1, 844 .num_bru_inputs = 5, 845 }, { 846 .version = VI6_IP_VERSION_MODEL_VSPDL_GEN3, 847 .model = "VSP2-DL", 848 .gen = 3, 849 .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_EXT_DL, 850 .lif_count = 2, 851 .rpf_count = 5, 852 .uif_count = 2, 853 .wpf_count = 2, 854 .num_bru_inputs = 5, 855 }, { 856 .version = VI6_IP_VERSION_MODEL_VSPD_GEN4, 857 .model = "VSP2-D", 858 .gen = 4, 859 .features = VSP1_HAS_BRU | VSP1_HAS_EXT_DL, 860 .lif_count = 1, 861 .rpf_count = 5, 862 .uif_count = 2, 863 .wpf_count = 1, 864 .num_bru_inputs = 5, 865 }, { 866 .version = VI6_IP_VERSION_MODEL_VSPX_GEN4, 867 .model = "VSP2-X", 868 .gen = 4, 869 .features = VSP1_HAS_IIF, 870 .rpf_count = 2, 871 .wpf_count = 1, 872 }, 873 }; 874 875 static const struct vsp1_device_info rzg2l_vsp2_device_info = { 876 .version = VI6_IP_VERSION_MODEL_VSPD_RZG2L, 877 .model = "VSP2-D", 878 .soc = VI6_IP_VERSION_SOC_RZG2L, 879 .gen = 3, 880 .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL 881 | VSP1_HAS_NON_ZERO_LBA, 882 .lif_count = 1, 883 .rpf_count = 2, 884 .wpf_count = 1, 885 }; 886 887 static const struct vsp1_device_info *vsp1_lookup_info(struct vsp1_device *vsp1) 888 { 889 const struct vsp1_device_info *info; 890 unsigned int i; 891 u32 model; 892 u32 soc; 893 894 /* 895 * Try the info stored in match data first for devices that don't have 896 * a version register. 897 */ 898 info = of_device_get_match_data(vsp1->dev); 899 if (info) { 900 vsp1->version = VI6_IP_VERSION_VSP_SW | info->version | info->soc; 901 return info; 902 } 903 904 vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION); 905 model = vsp1->version & VI6_IP_VERSION_MODEL_MASK; 906 soc = vsp1->version & VI6_IP_VERSION_SOC_MASK; 907 908 for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) { 909 info = &vsp1_device_infos[i]; 910 911 if (model == info->version && (!info->soc || soc == info->soc)) 912 return info; 913 } 914 915 dev_err(vsp1->dev, "unsupported IP version 0x%08x\n", vsp1->version); 916 917 return NULL; 918 } 919 920 static int vsp1_probe(struct platform_device *pdev) 921 { 922 struct vsp1_device *vsp1; 923 struct device_node *fcp_node; 924 int ret; 925 int irq; 926 927 vsp1 = devm_kzalloc(&pdev->dev, sizeof(*vsp1), GFP_KERNEL); 928 if (vsp1 == NULL) 929 return -ENOMEM; 930 931 vsp1->dev = &pdev->dev; 932 INIT_LIST_HEAD(&vsp1->entities); 933 INIT_LIST_HEAD(&vsp1->videos); 934 935 platform_set_drvdata(pdev, vsp1); 936 937 /* I/O and IRQ resources (clock managed by the clock PM domain). */ 938 vsp1->mmio = devm_platform_ioremap_resource(pdev, 0); 939 if (IS_ERR(vsp1->mmio)) 940 return PTR_ERR(vsp1->mmio); 941 942 irq = platform_get_irq(pdev, 0); 943 if (irq < 0) 944 return irq; 945 946 vsp1->rstc = devm_reset_control_get_shared(&pdev->dev, NULL); 947 if (IS_ERR(vsp1->rstc)) 948 return dev_err_probe(&pdev->dev, PTR_ERR(vsp1->rstc), 949 "failed to get reset control\n"); 950 951 /* FCP (optional). */ 952 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0); 953 if (fcp_node) { 954 vsp1->fcp = rcar_fcp_get(fcp_node); 955 of_node_put(fcp_node); 956 if (IS_ERR(vsp1->fcp)) { 957 dev_dbg(&pdev->dev, "FCP not found (%ld)\n", 958 PTR_ERR(vsp1->fcp)); 959 return PTR_ERR(vsp1->fcp); 960 } 961 962 /* 963 * When the FCP is present, it handles all bus master accesses 964 * for the VSP and must thus be used in place of the VSP device 965 * to map DMA buffers. 966 */ 967 vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp); 968 } else { 969 vsp1->bus_master = vsp1->dev; 970 } 971 972 /* Configure device parameters based on the version register. */ 973 pm_runtime_enable(&pdev->dev); 974 975 ret = vsp1_device_get(vsp1); 976 if (ret < 0) 977 goto done; 978 979 vsp1->info = vsp1_lookup_info(vsp1); 980 if (!vsp1->info) { 981 vsp1_device_put(vsp1); 982 ret = -ENXIO; 983 goto done; 984 } 985 986 dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version); 987 988 /* 989 * Previous use of the hardware (e.g. by the bootloader) could leave 990 * some interrupts enabled and pending. 991 * 992 * TODO: Investigate if this shouldn't be better handled by using the 993 * device reset provided by the CPG. 994 */ 995 vsp1_mask_all_interrupts(vsp1); 996 997 vsp1_device_put(vsp1); 998 999 ret = devm_request_irq(&pdev->dev, irq, vsp1_irq_handler, 1000 IRQF_SHARED, dev_name(&pdev->dev), vsp1); 1001 if (ret < 0) { 1002 dev_err(&pdev->dev, "failed to request IRQ\n"); 1003 goto done; 1004 } 1005 1006 /* Instantiate entities. */ 1007 ret = vsp1_create_entities(vsp1); 1008 if (ret < 0) { 1009 dev_err(&pdev->dev, "failed to create entities\n"); 1010 goto done; 1011 } 1012 1013 done: 1014 if (ret) { 1015 pm_runtime_disable(&pdev->dev); 1016 rcar_fcp_put(vsp1->fcp); 1017 } 1018 1019 return ret; 1020 } 1021 1022 static void vsp1_remove(struct platform_device *pdev) 1023 { 1024 struct vsp1_device *vsp1 = platform_get_drvdata(pdev); 1025 1026 vsp1_destroy_entities(vsp1); 1027 rcar_fcp_put(vsp1->fcp); 1028 1029 pm_runtime_disable(&pdev->dev); 1030 } 1031 1032 static const struct of_device_id vsp1_of_match[] = { 1033 { .compatible = "renesas,vsp1" }, 1034 { .compatible = "renesas,vsp2" }, 1035 { .compatible = "renesas,r9a07g044-vsp2", .data = &rzg2l_vsp2_device_info }, 1036 { }, 1037 }; 1038 MODULE_DEVICE_TABLE(of, vsp1_of_match); 1039 1040 static struct platform_driver vsp1_platform_driver = { 1041 .probe = vsp1_probe, 1042 .remove = vsp1_remove, 1043 .driver = { 1044 .name = "vsp1", 1045 .pm = &vsp1_pm_ops, 1046 .of_match_table = vsp1_of_match, 1047 }, 1048 }; 1049 1050 module_platform_driver(vsp1_platform_driver); 1051 1052 MODULE_ALIAS("vsp1"); 1053 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 1054 MODULE_DESCRIPTION("Renesas VSP1 Driver"); 1055 MODULE_LICENSE("GPL"); 1056