1 /* 2 * Copyright (C) 2013 Red Hat 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "msm_drv.h" 19 #include "msm_gpu.h" 20 #include "msm_kms.h" 21 22 static void msm_fb_output_poll_changed(struct drm_device *dev) 23 { 24 struct msm_drm_private *priv = dev->dev_private; 25 if (priv->fbdev) 26 drm_fb_helper_hotplug_event(priv->fbdev); 27 } 28 29 static const struct drm_mode_config_funcs mode_config_funcs = { 30 .fb_create = msm_framebuffer_create, 31 .output_poll_changed = msm_fb_output_poll_changed, 32 }; 33 34 int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu) 35 { 36 struct msm_drm_private *priv = dev->dev_private; 37 int idx = priv->num_mmus++; 38 39 if (WARN_ON(idx >= ARRAY_SIZE(priv->mmus))) 40 return -EINVAL; 41 42 priv->mmus[idx] = mmu; 43 44 return idx; 45 } 46 47 #ifdef CONFIG_DRM_MSM_REGISTER_LOGGING 48 static bool reglog = false; 49 MODULE_PARM_DESC(reglog, "Enable register read/write logging"); 50 module_param(reglog, bool, 0600); 51 #else 52 #define reglog 0 53 #endif 54 55 static char *vram; 56 MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); 57 module_param(vram, charp, 0); 58 59 /* 60 * Util/helpers: 61 */ 62 63 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 64 const char *dbgname) 65 { 66 struct resource *res; 67 unsigned long size; 68 void __iomem *ptr; 69 70 if (name) 71 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 72 else 73 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 74 75 if (!res) { 76 dev_err(&pdev->dev, "failed to get memory resource: %s\n", name); 77 return ERR_PTR(-EINVAL); 78 } 79 80 size = resource_size(res); 81 82 ptr = devm_ioremap_nocache(&pdev->dev, res->start, size); 83 if (!ptr) { 84 dev_err(&pdev->dev, "failed to ioremap: %s\n", name); 85 return ERR_PTR(-ENOMEM); 86 } 87 88 if (reglog) 89 printk(KERN_DEBUG "IO:region %s %08x %08lx\n", dbgname, (u32)ptr, size); 90 91 return ptr; 92 } 93 94 void msm_writel(u32 data, void __iomem *addr) 95 { 96 if (reglog) 97 printk(KERN_DEBUG "IO:W %08x %08x\n", (u32)addr, data); 98 writel(data, addr); 99 } 100 101 u32 msm_readl(const void __iomem *addr) 102 { 103 u32 val = readl(addr); 104 if (reglog) 105 printk(KERN_ERR "IO:R %08x %08x\n", (u32)addr, val); 106 return val; 107 } 108 109 /* 110 * DRM operations: 111 */ 112 113 static int msm_unload(struct drm_device *dev) 114 { 115 struct msm_drm_private *priv = dev->dev_private; 116 struct msm_kms *kms = priv->kms; 117 struct msm_gpu *gpu = priv->gpu; 118 119 drm_kms_helper_poll_fini(dev); 120 drm_mode_config_cleanup(dev); 121 drm_vblank_cleanup(dev); 122 123 pm_runtime_get_sync(dev->dev); 124 drm_irq_uninstall(dev); 125 pm_runtime_put_sync(dev->dev); 126 127 flush_workqueue(priv->wq); 128 destroy_workqueue(priv->wq); 129 130 if (kms) { 131 pm_runtime_disable(dev->dev); 132 kms->funcs->destroy(kms); 133 } 134 135 if (gpu) { 136 mutex_lock(&dev->struct_mutex); 137 gpu->funcs->pm_suspend(gpu); 138 gpu->funcs->destroy(gpu); 139 mutex_unlock(&dev->struct_mutex); 140 } 141 142 if (priv->vram.paddr) { 143 DEFINE_DMA_ATTRS(attrs); 144 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); 145 drm_mm_takedown(&priv->vram.mm); 146 dma_free_attrs(dev->dev, priv->vram.size, NULL, 147 priv->vram.paddr, &attrs); 148 } 149 150 component_unbind_all(dev->dev, dev); 151 152 dev->dev_private = NULL; 153 154 kfree(priv); 155 156 return 0; 157 } 158 159 static int get_mdp_ver(struct platform_device *pdev) 160 { 161 #ifdef CONFIG_OF 162 static const struct of_device_id match_types[] = { { 163 .compatible = "qcom,mdss_mdp", 164 .data = (void *)5, 165 }, { 166 /* end node */ 167 } }; 168 struct device *dev = &pdev->dev; 169 const struct of_device_id *match; 170 match = of_match_node(match_types, dev->of_node); 171 if (match) 172 return (int)match->data; 173 #endif 174 return 4; 175 } 176 177 static int msm_load(struct drm_device *dev, unsigned long flags) 178 { 179 struct platform_device *pdev = dev->platformdev; 180 struct msm_drm_private *priv; 181 struct msm_kms *kms; 182 int ret; 183 184 185 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 186 if (!priv) { 187 dev_err(dev->dev, "failed to allocate private data\n"); 188 return -ENOMEM; 189 } 190 191 dev->dev_private = priv; 192 193 priv->wq = alloc_ordered_workqueue("msm", 0); 194 init_waitqueue_head(&priv->fence_event); 195 196 INIT_LIST_HEAD(&priv->inactive_list); 197 INIT_LIST_HEAD(&priv->fence_cbs); 198 199 drm_mode_config_init(dev); 200 201 /* if we have no IOMMU, then we need to use carveout allocator. 202 * Grab the entire CMA chunk carved out in early startup in 203 * mach-msm: 204 */ 205 if (!iommu_present(&platform_bus_type)) { 206 DEFINE_DMA_ATTRS(attrs); 207 unsigned long size; 208 void *p; 209 210 DBG("using %s VRAM carveout", vram); 211 size = memparse(vram, NULL); 212 priv->vram.size = size; 213 214 drm_mm_init(&priv->vram.mm, 0, (size >> PAGE_SHIFT) - 1); 215 216 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); 217 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); 218 219 /* note that for no-kernel-mapping, the vaddr returned 220 * is bogus, but non-null if allocation succeeded: 221 */ 222 p = dma_alloc_attrs(dev->dev, size, 223 &priv->vram.paddr, GFP_KERNEL, &attrs); 224 if (!p) { 225 dev_err(dev->dev, "failed to allocate VRAM\n"); 226 priv->vram.paddr = 0; 227 ret = -ENOMEM; 228 goto fail; 229 } 230 231 dev_info(dev->dev, "VRAM: %08x->%08x\n", 232 (uint32_t)priv->vram.paddr, 233 (uint32_t)(priv->vram.paddr + size)); 234 } 235 236 platform_set_drvdata(pdev, dev); 237 238 /* Bind all our sub-components: */ 239 ret = component_bind_all(dev->dev, dev); 240 if (ret) 241 return ret; 242 243 switch (get_mdp_ver(pdev)) { 244 case 4: 245 kms = mdp4_kms_init(dev); 246 break; 247 case 5: 248 kms = mdp5_kms_init(dev); 249 break; 250 default: 251 kms = ERR_PTR(-ENODEV); 252 break; 253 } 254 255 if (IS_ERR(kms)) { 256 /* 257 * NOTE: once we have GPU support, having no kms should not 258 * be considered fatal.. ideally we would still support gpu 259 * and (for example) use dmabuf/prime to share buffers with 260 * imx drm driver on iMX5 261 */ 262 dev_err(dev->dev, "failed to load kms\n"); 263 ret = PTR_ERR(kms); 264 goto fail; 265 } 266 267 priv->kms = kms; 268 269 if (kms) { 270 pm_runtime_enable(dev->dev); 271 ret = kms->funcs->hw_init(kms); 272 if (ret) { 273 dev_err(dev->dev, "kms hw init failed: %d\n", ret); 274 goto fail; 275 } 276 } 277 278 dev->mode_config.min_width = 0; 279 dev->mode_config.min_height = 0; 280 dev->mode_config.max_width = 2048; 281 dev->mode_config.max_height = 2048; 282 dev->mode_config.funcs = &mode_config_funcs; 283 284 ret = drm_vblank_init(dev, 1); 285 if (ret < 0) { 286 dev_err(dev->dev, "failed to initialize vblank\n"); 287 goto fail; 288 } 289 290 pm_runtime_get_sync(dev->dev); 291 ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0)); 292 pm_runtime_put_sync(dev->dev); 293 if (ret < 0) { 294 dev_err(dev->dev, "failed to install IRQ handler\n"); 295 goto fail; 296 } 297 298 #ifdef CONFIG_DRM_MSM_FBDEV 299 priv->fbdev = msm_fbdev_init(dev); 300 #endif 301 302 ret = msm_debugfs_late_init(dev); 303 if (ret) 304 goto fail; 305 306 drm_kms_helper_poll_init(dev); 307 308 return 0; 309 310 fail: 311 msm_unload(dev); 312 return ret; 313 } 314 315 static void load_gpu(struct drm_device *dev) 316 { 317 struct msm_drm_private *priv = dev->dev_private; 318 struct msm_gpu *gpu; 319 320 if (priv->gpu) 321 return; 322 323 mutex_lock(&dev->struct_mutex); 324 gpu = a3xx_gpu_init(dev); 325 if (IS_ERR(gpu)) { 326 dev_warn(dev->dev, "failed to load a3xx gpu\n"); 327 gpu = NULL; 328 /* not fatal */ 329 } 330 331 if (gpu) { 332 int ret; 333 gpu->funcs->pm_resume(gpu); 334 ret = gpu->funcs->hw_init(gpu); 335 if (ret) { 336 dev_err(dev->dev, "gpu hw init failed: %d\n", ret); 337 gpu->funcs->destroy(gpu); 338 gpu = NULL; 339 } else { 340 /* give inactive pm a chance to kick in: */ 341 msm_gpu_retire(gpu); 342 } 343 344 } 345 346 priv->gpu = gpu; 347 348 mutex_unlock(&dev->struct_mutex); 349 } 350 351 static int msm_open(struct drm_device *dev, struct drm_file *file) 352 { 353 struct msm_file_private *ctx; 354 355 /* For now, load gpu on open.. to avoid the requirement of having 356 * firmware in the initrd. 357 */ 358 load_gpu(dev); 359 360 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 361 if (!ctx) 362 return -ENOMEM; 363 364 file->driver_priv = ctx; 365 366 return 0; 367 } 368 369 static void msm_preclose(struct drm_device *dev, struct drm_file *file) 370 { 371 struct msm_drm_private *priv = dev->dev_private; 372 struct msm_file_private *ctx = file->driver_priv; 373 struct msm_kms *kms = priv->kms; 374 375 if (kms) 376 kms->funcs->preclose(kms, file); 377 378 mutex_lock(&dev->struct_mutex); 379 if (ctx == priv->lastctx) 380 priv->lastctx = NULL; 381 mutex_unlock(&dev->struct_mutex); 382 383 kfree(ctx); 384 } 385 386 static void msm_lastclose(struct drm_device *dev) 387 { 388 struct msm_drm_private *priv = dev->dev_private; 389 if (priv->fbdev) 390 drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev); 391 } 392 393 static irqreturn_t msm_irq(int irq, void *arg) 394 { 395 struct drm_device *dev = arg; 396 struct msm_drm_private *priv = dev->dev_private; 397 struct msm_kms *kms = priv->kms; 398 BUG_ON(!kms); 399 return kms->funcs->irq(kms); 400 } 401 402 static void msm_irq_preinstall(struct drm_device *dev) 403 { 404 struct msm_drm_private *priv = dev->dev_private; 405 struct msm_kms *kms = priv->kms; 406 BUG_ON(!kms); 407 kms->funcs->irq_preinstall(kms); 408 } 409 410 static int msm_irq_postinstall(struct drm_device *dev) 411 { 412 struct msm_drm_private *priv = dev->dev_private; 413 struct msm_kms *kms = priv->kms; 414 BUG_ON(!kms); 415 return kms->funcs->irq_postinstall(kms); 416 } 417 418 static void msm_irq_uninstall(struct drm_device *dev) 419 { 420 struct msm_drm_private *priv = dev->dev_private; 421 struct msm_kms *kms = priv->kms; 422 BUG_ON(!kms); 423 kms->funcs->irq_uninstall(kms); 424 } 425 426 static int msm_enable_vblank(struct drm_device *dev, int crtc_id) 427 { 428 struct msm_drm_private *priv = dev->dev_private; 429 struct msm_kms *kms = priv->kms; 430 if (!kms) 431 return -ENXIO; 432 DBG("dev=%p, crtc=%d", dev, crtc_id); 433 return kms->funcs->enable_vblank(kms, priv->crtcs[crtc_id]); 434 } 435 436 static void msm_disable_vblank(struct drm_device *dev, int crtc_id) 437 { 438 struct msm_drm_private *priv = dev->dev_private; 439 struct msm_kms *kms = priv->kms; 440 if (!kms) 441 return; 442 DBG("dev=%p, crtc=%d", dev, crtc_id); 443 kms->funcs->disable_vblank(kms, priv->crtcs[crtc_id]); 444 } 445 446 /* 447 * DRM debugfs: 448 */ 449 450 #ifdef CONFIG_DEBUG_FS 451 static int msm_gpu_show(struct drm_device *dev, struct seq_file *m) 452 { 453 struct msm_drm_private *priv = dev->dev_private; 454 struct msm_gpu *gpu = priv->gpu; 455 456 if (gpu) { 457 seq_printf(m, "%s Status:\n", gpu->name); 458 gpu->funcs->show(gpu, m); 459 } 460 461 return 0; 462 } 463 464 static int msm_gem_show(struct drm_device *dev, struct seq_file *m) 465 { 466 struct msm_drm_private *priv = dev->dev_private; 467 struct msm_gpu *gpu = priv->gpu; 468 469 if (gpu) { 470 seq_printf(m, "Active Objects (%s):\n", gpu->name); 471 msm_gem_describe_objects(&gpu->active_list, m); 472 } 473 474 seq_printf(m, "Inactive Objects:\n"); 475 msm_gem_describe_objects(&priv->inactive_list, m); 476 477 return 0; 478 } 479 480 static int msm_mm_show(struct drm_device *dev, struct seq_file *m) 481 { 482 return drm_mm_dump_table(m, &dev->vma_offset_manager->vm_addr_space_mm); 483 } 484 485 static int msm_fb_show(struct drm_device *dev, struct seq_file *m) 486 { 487 struct msm_drm_private *priv = dev->dev_private; 488 struct drm_framebuffer *fb, *fbdev_fb = NULL; 489 490 if (priv->fbdev) { 491 seq_printf(m, "fbcon "); 492 fbdev_fb = priv->fbdev->fb; 493 msm_framebuffer_describe(fbdev_fb, m); 494 } 495 496 mutex_lock(&dev->mode_config.fb_lock); 497 list_for_each_entry(fb, &dev->mode_config.fb_list, head) { 498 if (fb == fbdev_fb) 499 continue; 500 501 seq_printf(m, "user "); 502 msm_framebuffer_describe(fb, m); 503 } 504 mutex_unlock(&dev->mode_config.fb_lock); 505 506 return 0; 507 } 508 509 static int show_locked(struct seq_file *m, void *arg) 510 { 511 struct drm_info_node *node = (struct drm_info_node *) m->private; 512 struct drm_device *dev = node->minor->dev; 513 int (*show)(struct drm_device *dev, struct seq_file *m) = 514 node->info_ent->data; 515 int ret; 516 517 ret = mutex_lock_interruptible(&dev->struct_mutex); 518 if (ret) 519 return ret; 520 521 ret = show(dev, m); 522 523 mutex_unlock(&dev->struct_mutex); 524 525 return ret; 526 } 527 528 static struct drm_info_list msm_debugfs_list[] = { 529 {"gpu", show_locked, 0, msm_gpu_show}, 530 {"gem", show_locked, 0, msm_gem_show}, 531 { "mm", show_locked, 0, msm_mm_show }, 532 { "fb", show_locked, 0, msm_fb_show }, 533 }; 534 535 static int late_init_minor(struct drm_minor *minor) 536 { 537 int ret; 538 539 if (!minor) 540 return 0; 541 542 ret = msm_rd_debugfs_init(minor); 543 if (ret) { 544 dev_err(minor->dev->dev, "could not install rd debugfs\n"); 545 return ret; 546 } 547 548 ret = msm_perf_debugfs_init(minor); 549 if (ret) { 550 dev_err(minor->dev->dev, "could not install perf debugfs\n"); 551 return ret; 552 } 553 554 return 0; 555 } 556 557 int msm_debugfs_late_init(struct drm_device *dev) 558 { 559 int ret; 560 ret = late_init_minor(dev->primary); 561 if (ret) 562 return ret; 563 ret = late_init_minor(dev->render); 564 if (ret) 565 return ret; 566 ret = late_init_minor(dev->control); 567 return ret; 568 } 569 570 static int msm_debugfs_init(struct drm_minor *minor) 571 { 572 struct drm_device *dev = minor->dev; 573 int ret; 574 575 ret = drm_debugfs_create_files(msm_debugfs_list, 576 ARRAY_SIZE(msm_debugfs_list), 577 minor->debugfs_root, minor); 578 579 if (ret) { 580 dev_err(dev->dev, "could not install msm_debugfs_list\n"); 581 return ret; 582 } 583 584 return 0; 585 } 586 587 static void msm_debugfs_cleanup(struct drm_minor *minor) 588 { 589 drm_debugfs_remove_files(msm_debugfs_list, 590 ARRAY_SIZE(msm_debugfs_list), minor); 591 if (!minor->dev->dev_private) 592 return; 593 msm_rd_debugfs_cleanup(minor); 594 msm_perf_debugfs_cleanup(minor); 595 } 596 #endif 597 598 /* 599 * Fences: 600 */ 601 602 int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, 603 struct timespec *timeout) 604 { 605 struct msm_drm_private *priv = dev->dev_private; 606 int ret; 607 608 if (!priv->gpu) 609 return 0; 610 611 if (fence > priv->gpu->submitted_fence) { 612 DRM_ERROR("waiting on invalid fence: %u (of %u)\n", 613 fence, priv->gpu->submitted_fence); 614 return -EINVAL; 615 } 616 617 if (!timeout) { 618 /* no-wait: */ 619 ret = fence_completed(dev, fence) ? 0 : -EBUSY; 620 } else { 621 unsigned long timeout_jiffies = timespec_to_jiffies(timeout); 622 unsigned long start_jiffies = jiffies; 623 unsigned long remaining_jiffies; 624 625 if (time_after(start_jiffies, timeout_jiffies)) 626 remaining_jiffies = 0; 627 else 628 remaining_jiffies = timeout_jiffies - start_jiffies; 629 630 ret = wait_event_interruptible_timeout(priv->fence_event, 631 fence_completed(dev, fence), 632 remaining_jiffies); 633 634 if (ret == 0) { 635 DBG("timeout waiting for fence: %u (completed: %u)", 636 fence, priv->completed_fence); 637 ret = -ETIMEDOUT; 638 } else if (ret != -ERESTARTSYS) { 639 ret = 0; 640 } 641 } 642 643 return ret; 644 } 645 646 /* called from workqueue */ 647 void msm_update_fence(struct drm_device *dev, uint32_t fence) 648 { 649 struct msm_drm_private *priv = dev->dev_private; 650 651 mutex_lock(&dev->struct_mutex); 652 priv->completed_fence = max(fence, priv->completed_fence); 653 654 while (!list_empty(&priv->fence_cbs)) { 655 struct msm_fence_cb *cb; 656 657 cb = list_first_entry(&priv->fence_cbs, 658 struct msm_fence_cb, work.entry); 659 660 if (cb->fence > priv->completed_fence) 661 break; 662 663 list_del_init(&cb->work.entry); 664 queue_work(priv->wq, &cb->work); 665 } 666 667 mutex_unlock(&dev->struct_mutex); 668 669 wake_up_all(&priv->fence_event); 670 } 671 672 void __msm_fence_worker(struct work_struct *work) 673 { 674 struct msm_fence_cb *cb = container_of(work, struct msm_fence_cb, work); 675 cb->func(cb); 676 } 677 678 /* 679 * DRM ioctls: 680 */ 681 682 static int msm_ioctl_get_param(struct drm_device *dev, void *data, 683 struct drm_file *file) 684 { 685 struct msm_drm_private *priv = dev->dev_private; 686 struct drm_msm_param *args = data; 687 struct msm_gpu *gpu; 688 689 /* for now, we just have 3d pipe.. eventually this would need to 690 * be more clever to dispatch to appropriate gpu module: 691 */ 692 if (args->pipe != MSM_PIPE_3D0) 693 return -EINVAL; 694 695 gpu = priv->gpu; 696 697 if (!gpu) 698 return -ENXIO; 699 700 return gpu->funcs->get_param(gpu, args->param, &args->value); 701 } 702 703 static int msm_ioctl_gem_new(struct drm_device *dev, void *data, 704 struct drm_file *file) 705 { 706 struct drm_msm_gem_new *args = data; 707 708 if (args->flags & ~MSM_BO_FLAGS) { 709 DRM_ERROR("invalid flags: %08x\n", args->flags); 710 return -EINVAL; 711 } 712 713 return msm_gem_new_handle(dev, file, args->size, 714 args->flags, &args->handle); 715 } 716 717 #define TS(t) ((struct timespec){ .tv_sec = (t).tv_sec, .tv_nsec = (t).tv_nsec }) 718 719 static int msm_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, 720 struct drm_file *file) 721 { 722 struct drm_msm_gem_cpu_prep *args = data; 723 struct drm_gem_object *obj; 724 int ret; 725 726 if (args->op & ~MSM_PREP_FLAGS) { 727 DRM_ERROR("invalid op: %08x\n", args->op); 728 return -EINVAL; 729 } 730 731 obj = drm_gem_object_lookup(dev, file, args->handle); 732 if (!obj) 733 return -ENOENT; 734 735 ret = msm_gem_cpu_prep(obj, args->op, &TS(args->timeout)); 736 737 drm_gem_object_unreference_unlocked(obj); 738 739 return ret; 740 } 741 742 static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, void *data, 743 struct drm_file *file) 744 { 745 struct drm_msm_gem_cpu_fini *args = data; 746 struct drm_gem_object *obj; 747 int ret; 748 749 obj = drm_gem_object_lookup(dev, file, args->handle); 750 if (!obj) 751 return -ENOENT; 752 753 ret = msm_gem_cpu_fini(obj); 754 755 drm_gem_object_unreference_unlocked(obj); 756 757 return ret; 758 } 759 760 static int msm_ioctl_gem_info(struct drm_device *dev, void *data, 761 struct drm_file *file) 762 { 763 struct drm_msm_gem_info *args = data; 764 struct drm_gem_object *obj; 765 int ret = 0; 766 767 if (args->pad) 768 return -EINVAL; 769 770 obj = drm_gem_object_lookup(dev, file, args->handle); 771 if (!obj) 772 return -ENOENT; 773 774 args->offset = msm_gem_mmap_offset(obj); 775 776 drm_gem_object_unreference_unlocked(obj); 777 778 return ret; 779 } 780 781 static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, 782 struct drm_file *file) 783 { 784 struct drm_msm_wait_fence *args = data; 785 786 if (args->pad) { 787 DRM_ERROR("invalid pad: %08x\n", args->pad); 788 return -EINVAL; 789 } 790 791 return msm_wait_fence_interruptable(dev, args->fence, 792 &TS(args->timeout)); 793 } 794 795 static const struct drm_ioctl_desc msm_ioctls[] = { 796 DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 797 DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 798 DRM_IOCTL_DEF_DRV(MSM_GEM_INFO, msm_ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 799 DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 800 DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 801 DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT, msm_ioctl_gem_submit, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 802 DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE, msm_ioctl_wait_fence, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 803 }; 804 805 static const struct vm_operations_struct vm_ops = { 806 .fault = msm_gem_fault, 807 .open = drm_gem_vm_open, 808 .close = drm_gem_vm_close, 809 }; 810 811 static const struct file_operations fops = { 812 .owner = THIS_MODULE, 813 .open = drm_open, 814 .release = drm_release, 815 .unlocked_ioctl = drm_ioctl, 816 #ifdef CONFIG_COMPAT 817 .compat_ioctl = drm_compat_ioctl, 818 #endif 819 .poll = drm_poll, 820 .read = drm_read, 821 .llseek = no_llseek, 822 .mmap = msm_gem_mmap, 823 }; 824 825 static struct drm_driver msm_driver = { 826 .driver_features = DRIVER_HAVE_IRQ | 827 DRIVER_GEM | 828 DRIVER_PRIME | 829 DRIVER_RENDER | 830 DRIVER_MODESET, 831 .load = msm_load, 832 .unload = msm_unload, 833 .open = msm_open, 834 .preclose = msm_preclose, 835 .lastclose = msm_lastclose, 836 .irq_handler = msm_irq, 837 .irq_preinstall = msm_irq_preinstall, 838 .irq_postinstall = msm_irq_postinstall, 839 .irq_uninstall = msm_irq_uninstall, 840 .get_vblank_counter = drm_vblank_count, 841 .enable_vblank = msm_enable_vblank, 842 .disable_vblank = msm_disable_vblank, 843 .gem_free_object = msm_gem_free_object, 844 .gem_vm_ops = &vm_ops, 845 .dumb_create = msm_gem_dumb_create, 846 .dumb_map_offset = msm_gem_dumb_map_offset, 847 .dumb_destroy = drm_gem_dumb_destroy, 848 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 849 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 850 .gem_prime_export = drm_gem_prime_export, 851 .gem_prime_import = drm_gem_prime_import, 852 .gem_prime_pin = msm_gem_prime_pin, 853 .gem_prime_unpin = msm_gem_prime_unpin, 854 .gem_prime_get_sg_table = msm_gem_prime_get_sg_table, 855 .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, 856 .gem_prime_vmap = msm_gem_prime_vmap, 857 .gem_prime_vunmap = msm_gem_prime_vunmap, 858 #ifdef CONFIG_DEBUG_FS 859 .debugfs_init = msm_debugfs_init, 860 .debugfs_cleanup = msm_debugfs_cleanup, 861 #endif 862 .ioctls = msm_ioctls, 863 .num_ioctls = DRM_MSM_NUM_IOCTLS, 864 .fops = &fops, 865 .name = "msm", 866 .desc = "MSM Snapdragon DRM", 867 .date = "20130625", 868 .major = 1, 869 .minor = 0, 870 }; 871 872 #ifdef CONFIG_PM_SLEEP 873 static int msm_pm_suspend(struct device *dev) 874 { 875 struct drm_device *ddev = dev_get_drvdata(dev); 876 877 drm_kms_helper_poll_disable(ddev); 878 879 return 0; 880 } 881 882 static int msm_pm_resume(struct device *dev) 883 { 884 struct drm_device *ddev = dev_get_drvdata(dev); 885 886 drm_kms_helper_poll_enable(ddev); 887 888 return 0; 889 } 890 #endif 891 892 static const struct dev_pm_ops msm_pm_ops = { 893 SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume) 894 }; 895 896 /* 897 * Componentized driver support: 898 */ 899 900 #ifdef CONFIG_OF 901 /* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx 902 * (or probably any other).. so probably some room for some helpers 903 */ 904 static int compare_of(struct device *dev, void *data) 905 { 906 return dev->of_node == data; 907 } 908 909 static int msm_drm_add_components(struct device *master, struct master *m) 910 { 911 struct device_node *np = master->of_node; 912 unsigned i; 913 int ret; 914 915 for (i = 0; ; i++) { 916 struct device_node *node; 917 918 node = of_parse_phandle(np, "connectors", i); 919 if (!node) 920 break; 921 922 ret = component_master_add_child(m, compare_of, node); 923 of_node_put(node); 924 925 if (ret) 926 return ret; 927 } 928 return 0; 929 } 930 #else 931 static int compare_dev(struct device *dev, void *data) 932 { 933 return dev == data; 934 } 935 936 static int msm_drm_add_components(struct device *master, struct master *m) 937 { 938 /* For non-DT case, it kinda sucks. We don't actually have a way 939 * to know whether or not we are waiting for certain devices (or if 940 * they are simply not present). But for non-DT we only need to 941 * care about apq8064/apq8060/etc (all mdp4/a3xx): 942 */ 943 static const char *devnames[] = { 944 "hdmi_msm.0", "kgsl-3d0.0", 945 }; 946 int i; 947 948 DBG("Adding components.."); 949 950 for (i = 0; i < ARRAY_SIZE(devnames); i++) { 951 struct device *dev; 952 int ret; 953 954 dev = bus_find_device_by_name(&platform_bus_type, 955 NULL, devnames[i]); 956 if (!dev) { 957 dev_info(master, "still waiting for %s\n", devnames[i]); 958 return -EPROBE_DEFER; 959 } 960 961 ret = component_master_add_child(m, compare_dev, dev); 962 if (ret) { 963 DBG("could not add child: %d", ret); 964 return ret; 965 } 966 } 967 968 return 0; 969 } 970 #endif 971 972 static int msm_drm_bind(struct device *dev) 973 { 974 return drm_platform_init(&msm_driver, to_platform_device(dev)); 975 } 976 977 static void msm_drm_unbind(struct device *dev) 978 { 979 drm_put_dev(platform_get_drvdata(to_platform_device(dev))); 980 } 981 982 static const struct component_master_ops msm_drm_ops = { 983 .add_components = msm_drm_add_components, 984 .bind = msm_drm_bind, 985 .unbind = msm_drm_unbind, 986 }; 987 988 /* 989 * Platform driver: 990 */ 991 992 static int msm_pdev_probe(struct platform_device *pdev) 993 { 994 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 995 return component_master_add(&pdev->dev, &msm_drm_ops); 996 } 997 998 static int msm_pdev_remove(struct platform_device *pdev) 999 { 1000 component_master_del(&pdev->dev, &msm_drm_ops); 1001 1002 return 0; 1003 } 1004 1005 static const struct platform_device_id msm_id[] = { 1006 { "mdp", 0 }, 1007 { } 1008 }; 1009 1010 static const struct of_device_id dt_match[] = { 1011 { .compatible = "qcom,mdss_mdp" }, 1012 {} 1013 }; 1014 MODULE_DEVICE_TABLE(of, dt_match); 1015 1016 static struct platform_driver msm_platform_driver = { 1017 .probe = msm_pdev_probe, 1018 .remove = msm_pdev_remove, 1019 .driver = { 1020 .owner = THIS_MODULE, 1021 .name = "msm", 1022 .of_match_table = dt_match, 1023 .pm = &msm_pm_ops, 1024 }, 1025 .id_table = msm_id, 1026 }; 1027 1028 static int __init msm_drm_register(void) 1029 { 1030 DBG("init"); 1031 hdmi_register(); 1032 a3xx_register(); 1033 return platform_driver_register(&msm_platform_driver); 1034 } 1035 1036 static void __exit msm_drm_unregister(void) 1037 { 1038 DBG("fini"); 1039 platform_driver_unregister(&msm_platform_driver); 1040 hdmi_unregister(); 1041 a3xx_unregister(); 1042 } 1043 1044 module_init(msm_drm_register); 1045 module_exit(msm_drm_unregister); 1046 1047 MODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 1048 MODULE_DESCRIPTION("MSM DRM Driver"); 1049 MODULE_LICENSE("GPL"); 1050