1 /* 2 * Copyright (C) 2012 Avionic Design GmbH 3 * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10 #include <linux/host1x.h> 11 #include <linux/iommu.h> 12 13 #include "drm.h" 14 #include "gem.h" 15 16 #define DRIVER_NAME "tegra" 17 #define DRIVER_DESC "NVIDIA Tegra graphics" 18 #define DRIVER_DATE "20120330" 19 #define DRIVER_MAJOR 0 20 #define DRIVER_MINOR 0 21 #define DRIVER_PATCHLEVEL 0 22 23 struct tegra_drm_file { 24 struct list_head contexts; 25 }; 26 27 static int tegra_drm_load(struct drm_device *drm, unsigned long flags) 28 { 29 struct host1x_device *device = to_host1x_device(drm->dev); 30 struct tegra_drm *tegra; 31 int err; 32 33 tegra = kzalloc(sizeof(*tegra), GFP_KERNEL); 34 if (!tegra) 35 return -ENOMEM; 36 37 if (iommu_present(&platform_bus_type)) { 38 tegra->domain = iommu_domain_alloc(&platform_bus_type); 39 if (IS_ERR(tegra->domain)) { 40 err = PTR_ERR(tegra->domain); 41 goto free; 42 } 43 44 DRM_DEBUG("IOMMU context initialized\n"); 45 drm_mm_init(&tegra->mm, 0, SZ_2G); 46 } 47 48 mutex_init(&tegra->clients_lock); 49 INIT_LIST_HEAD(&tegra->clients); 50 drm->dev_private = tegra; 51 tegra->drm = drm; 52 53 drm_mode_config_init(drm); 54 55 err = tegra_drm_fb_prepare(drm); 56 if (err < 0) 57 goto config; 58 59 drm_kms_helper_poll_init(drm); 60 61 err = host1x_device_init(device); 62 if (err < 0) 63 goto fbdev; 64 65 /* 66 * We don't use the drm_irq_install() helpers provided by the DRM 67 * core, so we need to set this manually in order to allow the 68 * DRM_IOCTL_WAIT_VBLANK to operate correctly. 69 */ 70 drm->irq_enabled = true; 71 72 err = drm_vblank_init(drm, drm->mode_config.num_crtc); 73 if (err < 0) 74 goto device; 75 76 err = tegra_drm_fb_init(drm); 77 if (err < 0) 78 goto vblank; 79 80 return 0; 81 82 vblank: 83 drm_vblank_cleanup(drm); 84 device: 85 host1x_device_exit(device); 86 fbdev: 87 drm_kms_helper_poll_fini(drm); 88 tegra_drm_fb_free(drm); 89 config: 90 drm_mode_config_cleanup(drm); 91 92 if (tegra->domain) { 93 iommu_domain_free(tegra->domain); 94 drm_mm_takedown(&tegra->mm); 95 } 96 free: 97 kfree(tegra); 98 return err; 99 } 100 101 static int tegra_drm_unload(struct drm_device *drm) 102 { 103 struct host1x_device *device = to_host1x_device(drm->dev); 104 struct tegra_drm *tegra = drm->dev_private; 105 int err; 106 107 drm_kms_helper_poll_fini(drm); 108 tegra_drm_fb_exit(drm); 109 drm_vblank_cleanup(drm); 110 drm_mode_config_cleanup(drm); 111 112 err = host1x_device_exit(device); 113 if (err < 0) 114 return err; 115 116 if (tegra->domain) { 117 iommu_domain_free(tegra->domain); 118 drm_mm_takedown(&tegra->mm); 119 } 120 121 kfree(tegra); 122 123 return 0; 124 } 125 126 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp) 127 { 128 struct tegra_drm_file *fpriv; 129 130 fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); 131 if (!fpriv) 132 return -ENOMEM; 133 134 INIT_LIST_HEAD(&fpriv->contexts); 135 filp->driver_priv = fpriv; 136 137 return 0; 138 } 139 140 static void tegra_drm_context_free(struct tegra_drm_context *context) 141 { 142 context->client->ops->close_channel(context); 143 kfree(context); 144 } 145 146 static void tegra_drm_lastclose(struct drm_device *drm) 147 { 148 #ifdef CONFIG_DRM_TEGRA_FBDEV 149 struct tegra_drm *tegra = drm->dev_private; 150 151 tegra_fbdev_restore_mode(tegra->fbdev); 152 #endif 153 } 154 155 static struct host1x_bo * 156 host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) 157 { 158 struct drm_gem_object *gem; 159 struct tegra_bo *bo; 160 161 gem = drm_gem_object_lookup(drm, file, handle); 162 if (!gem) 163 return NULL; 164 165 mutex_lock(&drm->struct_mutex); 166 drm_gem_object_unreference(gem); 167 mutex_unlock(&drm->struct_mutex); 168 169 bo = to_tegra_bo(gem); 170 return &bo->base; 171 } 172 173 static int host1x_reloc_copy_from_user(struct host1x_reloc *dest, 174 struct drm_tegra_reloc __user *src, 175 struct drm_device *drm, 176 struct drm_file *file) 177 { 178 u32 cmdbuf, target; 179 int err; 180 181 err = get_user(cmdbuf, &src->cmdbuf.handle); 182 if (err < 0) 183 return err; 184 185 err = get_user(dest->cmdbuf.offset, &src->cmdbuf.offset); 186 if (err < 0) 187 return err; 188 189 err = get_user(target, &src->target.handle); 190 if (err < 0) 191 return err; 192 193 err = get_user(dest->target.offset, &src->cmdbuf.offset); 194 if (err < 0) 195 return err; 196 197 err = get_user(dest->shift, &src->shift); 198 if (err < 0) 199 return err; 200 201 dest->cmdbuf.bo = host1x_bo_lookup(drm, file, cmdbuf); 202 if (!dest->cmdbuf.bo) 203 return -ENOENT; 204 205 dest->target.bo = host1x_bo_lookup(drm, file, target); 206 if (!dest->target.bo) 207 return -ENOENT; 208 209 return 0; 210 } 211 212 int tegra_drm_submit(struct tegra_drm_context *context, 213 struct drm_tegra_submit *args, struct drm_device *drm, 214 struct drm_file *file) 215 { 216 unsigned int num_cmdbufs = args->num_cmdbufs; 217 unsigned int num_relocs = args->num_relocs; 218 unsigned int num_waitchks = args->num_waitchks; 219 struct drm_tegra_cmdbuf __user *cmdbufs = 220 (void __user *)(uintptr_t)args->cmdbufs; 221 struct drm_tegra_reloc __user *relocs = 222 (void __user *)(uintptr_t)args->relocs; 223 struct drm_tegra_waitchk __user *waitchks = 224 (void __user *)(uintptr_t)args->waitchks; 225 struct drm_tegra_syncpt syncpt; 226 struct host1x_job *job; 227 int err; 228 229 /* We don't yet support other than one syncpt_incr struct per submit */ 230 if (args->num_syncpts != 1) 231 return -EINVAL; 232 233 job = host1x_job_alloc(context->channel, args->num_cmdbufs, 234 args->num_relocs, args->num_waitchks); 235 if (!job) 236 return -ENOMEM; 237 238 job->num_relocs = args->num_relocs; 239 job->num_waitchk = args->num_waitchks; 240 job->client = (u32)args->context; 241 job->class = context->client->base.class; 242 job->serialize = true; 243 244 while (num_cmdbufs) { 245 struct drm_tegra_cmdbuf cmdbuf; 246 struct host1x_bo *bo; 247 248 if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) { 249 err = -EFAULT; 250 goto fail; 251 } 252 253 bo = host1x_bo_lookup(drm, file, cmdbuf.handle); 254 if (!bo) { 255 err = -ENOENT; 256 goto fail; 257 } 258 259 host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); 260 num_cmdbufs--; 261 cmdbufs++; 262 } 263 264 /* copy and resolve relocations from submit */ 265 while (num_relocs--) { 266 err = host1x_reloc_copy_from_user(&job->relocarray[num_relocs], 267 &relocs[num_relocs], drm, 268 file); 269 if (err < 0) 270 goto fail; 271 } 272 273 if (copy_from_user(job->waitchk, waitchks, 274 sizeof(*waitchks) * num_waitchks)) { 275 err = -EFAULT; 276 goto fail; 277 } 278 279 if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts, 280 sizeof(syncpt))) { 281 err = -EFAULT; 282 goto fail; 283 } 284 285 job->is_addr_reg = context->client->ops->is_addr_reg; 286 job->syncpt_incrs = syncpt.incrs; 287 job->syncpt_id = syncpt.id; 288 job->timeout = 10000; 289 290 if (args->timeout && args->timeout < 10000) 291 job->timeout = args->timeout; 292 293 err = host1x_job_pin(job, context->client->base.dev); 294 if (err) 295 goto fail; 296 297 err = host1x_job_submit(job); 298 if (err) 299 goto fail_submit; 300 301 args->fence = job->syncpt_end; 302 303 host1x_job_put(job); 304 return 0; 305 306 fail_submit: 307 host1x_job_unpin(job); 308 fail: 309 host1x_job_put(job); 310 return err; 311 } 312 313 314 #ifdef CONFIG_DRM_TEGRA_STAGING 315 static struct tegra_drm_context *tegra_drm_get_context(__u64 context) 316 { 317 return (struct tegra_drm_context *)(uintptr_t)context; 318 } 319 320 static bool tegra_drm_file_owns_context(struct tegra_drm_file *file, 321 struct tegra_drm_context *context) 322 { 323 struct tegra_drm_context *ctx; 324 325 list_for_each_entry(ctx, &file->contexts, list) 326 if (ctx == context) 327 return true; 328 329 return false; 330 } 331 332 static int tegra_gem_create(struct drm_device *drm, void *data, 333 struct drm_file *file) 334 { 335 struct drm_tegra_gem_create *args = data; 336 struct tegra_bo *bo; 337 338 bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags, 339 &args->handle); 340 if (IS_ERR(bo)) 341 return PTR_ERR(bo); 342 343 return 0; 344 } 345 346 static int tegra_gem_mmap(struct drm_device *drm, void *data, 347 struct drm_file *file) 348 { 349 struct drm_tegra_gem_mmap *args = data; 350 struct drm_gem_object *gem; 351 struct tegra_bo *bo; 352 353 gem = drm_gem_object_lookup(drm, file, args->handle); 354 if (!gem) 355 return -EINVAL; 356 357 bo = to_tegra_bo(gem); 358 359 args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node); 360 361 drm_gem_object_unreference(gem); 362 363 return 0; 364 } 365 366 static int tegra_syncpt_read(struct drm_device *drm, void *data, 367 struct drm_file *file) 368 { 369 struct host1x *host = dev_get_drvdata(drm->dev->parent); 370 struct drm_tegra_syncpt_read *args = data; 371 struct host1x_syncpt *sp; 372 373 sp = host1x_syncpt_get(host, args->id); 374 if (!sp) 375 return -EINVAL; 376 377 args->value = host1x_syncpt_read_min(sp); 378 return 0; 379 } 380 381 static int tegra_syncpt_incr(struct drm_device *drm, void *data, 382 struct drm_file *file) 383 { 384 struct host1x *host1x = dev_get_drvdata(drm->dev->parent); 385 struct drm_tegra_syncpt_incr *args = data; 386 struct host1x_syncpt *sp; 387 388 sp = host1x_syncpt_get(host1x, args->id); 389 if (!sp) 390 return -EINVAL; 391 392 return host1x_syncpt_incr(sp); 393 } 394 395 static int tegra_syncpt_wait(struct drm_device *drm, void *data, 396 struct drm_file *file) 397 { 398 struct host1x *host1x = dev_get_drvdata(drm->dev->parent); 399 struct drm_tegra_syncpt_wait *args = data; 400 struct host1x_syncpt *sp; 401 402 sp = host1x_syncpt_get(host1x, args->id); 403 if (!sp) 404 return -EINVAL; 405 406 return host1x_syncpt_wait(sp, args->thresh, args->timeout, 407 &args->value); 408 } 409 410 static int tegra_open_channel(struct drm_device *drm, void *data, 411 struct drm_file *file) 412 { 413 struct tegra_drm_file *fpriv = file->driver_priv; 414 struct tegra_drm *tegra = drm->dev_private; 415 struct drm_tegra_open_channel *args = data; 416 struct tegra_drm_context *context; 417 struct tegra_drm_client *client; 418 int err = -ENODEV; 419 420 context = kzalloc(sizeof(*context), GFP_KERNEL); 421 if (!context) 422 return -ENOMEM; 423 424 list_for_each_entry(client, &tegra->clients, list) 425 if (client->base.class == args->client) { 426 err = client->ops->open_channel(client, context); 427 if (err) 428 break; 429 430 list_add(&context->list, &fpriv->contexts); 431 args->context = (uintptr_t)context; 432 context->client = client; 433 return 0; 434 } 435 436 kfree(context); 437 return err; 438 } 439 440 static int tegra_close_channel(struct drm_device *drm, void *data, 441 struct drm_file *file) 442 { 443 struct tegra_drm_file *fpriv = file->driver_priv; 444 struct drm_tegra_close_channel *args = data; 445 struct tegra_drm_context *context; 446 447 context = tegra_drm_get_context(args->context); 448 449 if (!tegra_drm_file_owns_context(fpriv, context)) 450 return -EINVAL; 451 452 list_del(&context->list); 453 tegra_drm_context_free(context); 454 455 return 0; 456 } 457 458 static int tegra_get_syncpt(struct drm_device *drm, void *data, 459 struct drm_file *file) 460 { 461 struct tegra_drm_file *fpriv = file->driver_priv; 462 struct drm_tegra_get_syncpt *args = data; 463 struct tegra_drm_context *context; 464 struct host1x_syncpt *syncpt; 465 466 context = tegra_drm_get_context(args->context); 467 468 if (!tegra_drm_file_owns_context(fpriv, context)) 469 return -ENODEV; 470 471 if (args->index >= context->client->base.num_syncpts) 472 return -EINVAL; 473 474 syncpt = context->client->base.syncpts[args->index]; 475 args->id = host1x_syncpt_id(syncpt); 476 477 return 0; 478 } 479 480 static int tegra_submit(struct drm_device *drm, void *data, 481 struct drm_file *file) 482 { 483 struct tegra_drm_file *fpriv = file->driver_priv; 484 struct drm_tegra_submit *args = data; 485 struct tegra_drm_context *context; 486 487 context = tegra_drm_get_context(args->context); 488 489 if (!tegra_drm_file_owns_context(fpriv, context)) 490 return -ENODEV; 491 492 return context->client->ops->submit(context, args, drm, file); 493 } 494 495 static int tegra_get_syncpt_base(struct drm_device *drm, void *data, 496 struct drm_file *file) 497 { 498 struct tegra_drm_file *fpriv = file->driver_priv; 499 struct drm_tegra_get_syncpt_base *args = data; 500 struct tegra_drm_context *context; 501 struct host1x_syncpt_base *base; 502 struct host1x_syncpt *syncpt; 503 504 context = tegra_drm_get_context(args->context); 505 506 if (!tegra_drm_file_owns_context(fpriv, context)) 507 return -ENODEV; 508 509 if (args->syncpt >= context->client->base.num_syncpts) 510 return -EINVAL; 511 512 syncpt = context->client->base.syncpts[args->syncpt]; 513 514 base = host1x_syncpt_get_base(syncpt); 515 if (!base) 516 return -ENXIO; 517 518 args->id = host1x_syncpt_base_id(base); 519 520 return 0; 521 } 522 523 static int tegra_gem_set_tiling(struct drm_device *drm, void *data, 524 struct drm_file *file) 525 { 526 struct drm_tegra_gem_set_tiling *args = data; 527 enum tegra_bo_tiling_mode mode; 528 struct drm_gem_object *gem; 529 unsigned long value = 0; 530 struct tegra_bo *bo; 531 532 switch (args->mode) { 533 case DRM_TEGRA_GEM_TILING_MODE_PITCH: 534 mode = TEGRA_BO_TILING_MODE_PITCH; 535 536 if (args->value != 0) 537 return -EINVAL; 538 539 break; 540 541 case DRM_TEGRA_GEM_TILING_MODE_TILED: 542 mode = TEGRA_BO_TILING_MODE_TILED; 543 544 if (args->value != 0) 545 return -EINVAL; 546 547 break; 548 549 case DRM_TEGRA_GEM_TILING_MODE_BLOCK: 550 mode = TEGRA_BO_TILING_MODE_BLOCK; 551 552 if (args->value > 5) 553 return -EINVAL; 554 555 value = args->value; 556 break; 557 558 default: 559 return -EINVAL; 560 } 561 562 gem = drm_gem_object_lookup(drm, file, args->handle); 563 if (!gem) 564 return -ENOENT; 565 566 bo = to_tegra_bo(gem); 567 568 bo->tiling.mode = mode; 569 bo->tiling.value = value; 570 571 drm_gem_object_unreference(gem); 572 573 return 0; 574 } 575 576 static int tegra_gem_get_tiling(struct drm_device *drm, void *data, 577 struct drm_file *file) 578 { 579 struct drm_tegra_gem_get_tiling *args = data; 580 struct drm_gem_object *gem; 581 struct tegra_bo *bo; 582 int err = 0; 583 584 gem = drm_gem_object_lookup(drm, file, args->handle); 585 if (!gem) 586 return -ENOENT; 587 588 bo = to_tegra_bo(gem); 589 590 switch (bo->tiling.mode) { 591 case TEGRA_BO_TILING_MODE_PITCH: 592 args->mode = DRM_TEGRA_GEM_TILING_MODE_PITCH; 593 args->value = 0; 594 break; 595 596 case TEGRA_BO_TILING_MODE_TILED: 597 args->mode = DRM_TEGRA_GEM_TILING_MODE_TILED; 598 args->value = 0; 599 break; 600 601 case TEGRA_BO_TILING_MODE_BLOCK: 602 args->mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK; 603 args->value = bo->tiling.value; 604 break; 605 606 default: 607 err = -EINVAL; 608 break; 609 } 610 611 drm_gem_object_unreference(gem); 612 613 return err; 614 } 615 616 static int tegra_gem_set_flags(struct drm_device *drm, void *data, 617 struct drm_file *file) 618 { 619 struct drm_tegra_gem_set_flags *args = data; 620 struct drm_gem_object *gem; 621 struct tegra_bo *bo; 622 623 if (args->flags & ~DRM_TEGRA_GEM_FLAGS) 624 return -EINVAL; 625 626 gem = drm_gem_object_lookup(drm, file, args->handle); 627 if (!gem) 628 return -ENOENT; 629 630 bo = to_tegra_bo(gem); 631 bo->flags = 0; 632 633 if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP) 634 bo->flags |= TEGRA_BO_BOTTOM_UP; 635 636 drm_gem_object_unreference(gem); 637 638 return 0; 639 } 640 641 static int tegra_gem_get_flags(struct drm_device *drm, void *data, 642 struct drm_file *file) 643 { 644 struct drm_tegra_gem_get_flags *args = data; 645 struct drm_gem_object *gem; 646 struct tegra_bo *bo; 647 648 gem = drm_gem_object_lookup(drm, file, args->handle); 649 if (!gem) 650 return -ENOENT; 651 652 bo = to_tegra_bo(gem); 653 args->flags = 0; 654 655 if (bo->flags & TEGRA_BO_BOTTOM_UP) 656 args->flags |= DRM_TEGRA_GEM_BOTTOM_UP; 657 658 drm_gem_object_unreference(gem); 659 660 return 0; 661 } 662 #endif 663 664 static const struct drm_ioctl_desc tegra_drm_ioctls[] = { 665 #ifdef CONFIG_DRM_TEGRA_STAGING 666 DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED), 667 DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_UNLOCKED), 668 DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, DRM_UNLOCKED), 669 DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, DRM_UNLOCKED), 670 DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, DRM_UNLOCKED), 671 DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, DRM_UNLOCKED), 672 DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, DRM_UNLOCKED), 673 DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, DRM_UNLOCKED), 674 DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, DRM_UNLOCKED), 675 DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, DRM_UNLOCKED), 676 DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, DRM_UNLOCKED), 677 DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, DRM_UNLOCKED), 678 DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, DRM_UNLOCKED), 679 DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, DRM_UNLOCKED), 680 #endif 681 }; 682 683 static const struct file_operations tegra_drm_fops = { 684 .owner = THIS_MODULE, 685 .open = drm_open, 686 .release = drm_release, 687 .unlocked_ioctl = drm_ioctl, 688 .mmap = tegra_drm_mmap, 689 .poll = drm_poll, 690 .read = drm_read, 691 #ifdef CONFIG_COMPAT 692 .compat_ioctl = drm_compat_ioctl, 693 #endif 694 .llseek = noop_llseek, 695 }; 696 697 static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, 698 unsigned int pipe) 699 { 700 struct drm_crtc *crtc; 701 702 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { 703 if (pipe == drm_crtc_index(crtc)) 704 return crtc; 705 } 706 707 return NULL; 708 } 709 710 static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) 711 { 712 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); 713 714 if (!crtc) 715 return 0; 716 717 /* TODO: implement real hardware counter using syncpoints */ 718 return drm_crtc_vblank_count(crtc); 719 } 720 721 static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) 722 { 723 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); 724 struct tegra_dc *dc = to_tegra_dc(crtc); 725 726 if (!crtc) 727 return -ENODEV; 728 729 tegra_dc_enable_vblank(dc); 730 731 return 0; 732 } 733 734 static void tegra_drm_disable_vblank(struct drm_device *drm, int pipe) 735 { 736 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); 737 struct tegra_dc *dc = to_tegra_dc(crtc); 738 739 if (crtc) 740 tegra_dc_disable_vblank(dc); 741 } 742 743 static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file) 744 { 745 struct tegra_drm_file *fpriv = file->driver_priv; 746 struct tegra_drm_context *context, *tmp; 747 struct drm_crtc *crtc; 748 749 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) 750 tegra_dc_cancel_page_flip(crtc, file); 751 752 list_for_each_entry_safe(context, tmp, &fpriv->contexts, list) 753 tegra_drm_context_free(context); 754 755 kfree(fpriv); 756 } 757 758 #ifdef CONFIG_DEBUG_FS 759 static int tegra_debugfs_framebuffers(struct seq_file *s, void *data) 760 { 761 struct drm_info_node *node = (struct drm_info_node *)s->private; 762 struct drm_device *drm = node->minor->dev; 763 struct drm_framebuffer *fb; 764 765 mutex_lock(&drm->mode_config.fb_lock); 766 767 list_for_each_entry(fb, &drm->mode_config.fb_list, head) { 768 seq_printf(s, "%3d: user size: %d x %d, depth %d, %d bpp, refcount %d\n", 769 fb->base.id, fb->width, fb->height, fb->depth, 770 fb->bits_per_pixel, 771 atomic_read(&fb->refcount.refcount)); 772 } 773 774 mutex_unlock(&drm->mode_config.fb_lock); 775 776 return 0; 777 } 778 779 static struct drm_info_list tegra_debugfs_list[] = { 780 { "framebuffers", tegra_debugfs_framebuffers, 0 }, 781 }; 782 783 static int tegra_debugfs_init(struct drm_minor *minor) 784 { 785 return drm_debugfs_create_files(tegra_debugfs_list, 786 ARRAY_SIZE(tegra_debugfs_list), 787 minor->debugfs_root, minor); 788 } 789 790 static void tegra_debugfs_cleanup(struct drm_minor *minor) 791 { 792 drm_debugfs_remove_files(tegra_debugfs_list, 793 ARRAY_SIZE(tegra_debugfs_list), minor); 794 } 795 #endif 796 797 static struct drm_driver tegra_drm_driver = { 798 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, 799 .load = tegra_drm_load, 800 .unload = tegra_drm_unload, 801 .open = tegra_drm_open, 802 .preclose = tegra_drm_preclose, 803 .lastclose = tegra_drm_lastclose, 804 805 .get_vblank_counter = tegra_drm_get_vblank_counter, 806 .enable_vblank = tegra_drm_enable_vblank, 807 .disable_vblank = tegra_drm_disable_vblank, 808 809 #if defined(CONFIG_DEBUG_FS) 810 .debugfs_init = tegra_debugfs_init, 811 .debugfs_cleanup = tegra_debugfs_cleanup, 812 #endif 813 814 .gem_free_object = tegra_bo_free_object, 815 .gem_vm_ops = &tegra_bo_vm_ops, 816 817 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 818 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 819 .gem_prime_export = tegra_gem_prime_export, 820 .gem_prime_import = tegra_gem_prime_import, 821 822 .dumb_create = tegra_bo_dumb_create, 823 .dumb_map_offset = tegra_bo_dumb_map_offset, 824 .dumb_destroy = drm_gem_dumb_destroy, 825 826 .ioctls = tegra_drm_ioctls, 827 .num_ioctls = ARRAY_SIZE(tegra_drm_ioctls), 828 .fops = &tegra_drm_fops, 829 830 .name = DRIVER_NAME, 831 .desc = DRIVER_DESC, 832 .date = DRIVER_DATE, 833 .major = DRIVER_MAJOR, 834 .minor = DRIVER_MINOR, 835 .patchlevel = DRIVER_PATCHLEVEL, 836 }; 837 838 int tegra_drm_register_client(struct tegra_drm *tegra, 839 struct tegra_drm_client *client) 840 { 841 mutex_lock(&tegra->clients_lock); 842 list_add_tail(&client->list, &tegra->clients); 843 mutex_unlock(&tegra->clients_lock); 844 845 return 0; 846 } 847 848 int tegra_drm_unregister_client(struct tegra_drm *tegra, 849 struct tegra_drm_client *client) 850 { 851 mutex_lock(&tegra->clients_lock); 852 list_del_init(&client->list); 853 mutex_unlock(&tegra->clients_lock); 854 855 return 0; 856 } 857 858 static int host1x_drm_probe(struct host1x_device *dev) 859 { 860 struct drm_driver *driver = &tegra_drm_driver; 861 struct drm_device *drm; 862 int err; 863 864 drm = drm_dev_alloc(driver, &dev->dev); 865 if (!drm) 866 return -ENOMEM; 867 868 drm_dev_set_unique(drm, dev_name(&dev->dev)); 869 dev_set_drvdata(&dev->dev, drm); 870 871 err = drm_dev_register(drm, 0); 872 if (err < 0) 873 goto unref; 874 875 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, 876 driver->major, driver->minor, driver->patchlevel, 877 driver->date, drm->primary->index); 878 879 return 0; 880 881 unref: 882 drm_dev_unref(drm); 883 return err; 884 } 885 886 static int host1x_drm_remove(struct host1x_device *dev) 887 { 888 struct drm_device *drm = dev_get_drvdata(&dev->dev); 889 890 drm_dev_unregister(drm); 891 drm_dev_unref(drm); 892 893 return 0; 894 } 895 896 static const struct of_device_id host1x_drm_subdevs[] = { 897 { .compatible = "nvidia,tegra20-dc", }, 898 { .compatible = "nvidia,tegra20-hdmi", }, 899 { .compatible = "nvidia,tegra20-gr2d", }, 900 { .compatible = "nvidia,tegra20-gr3d", }, 901 { .compatible = "nvidia,tegra30-dc", }, 902 { .compatible = "nvidia,tegra30-hdmi", }, 903 { .compatible = "nvidia,tegra30-gr2d", }, 904 { .compatible = "nvidia,tegra30-gr3d", }, 905 { .compatible = "nvidia,tegra114-dsi", }, 906 { .compatible = "nvidia,tegra114-hdmi", }, 907 { .compatible = "nvidia,tegra114-gr3d", }, 908 { .compatible = "nvidia,tegra124-dc", }, 909 { .compatible = "nvidia,tegra124-sor", }, 910 { .compatible = "nvidia,tegra124-hdmi", }, 911 { /* sentinel */ } 912 }; 913 914 static struct host1x_driver host1x_drm_driver = { 915 .name = "drm", 916 .probe = host1x_drm_probe, 917 .remove = host1x_drm_remove, 918 .subdevs = host1x_drm_subdevs, 919 }; 920 921 static int __init host1x_drm_init(void) 922 { 923 int err; 924 925 err = host1x_driver_register(&host1x_drm_driver); 926 if (err < 0) 927 return err; 928 929 err = platform_driver_register(&tegra_dc_driver); 930 if (err < 0) 931 goto unregister_host1x; 932 933 err = platform_driver_register(&tegra_dsi_driver); 934 if (err < 0) 935 goto unregister_dc; 936 937 err = platform_driver_register(&tegra_sor_driver); 938 if (err < 0) 939 goto unregister_dsi; 940 941 err = platform_driver_register(&tegra_hdmi_driver); 942 if (err < 0) 943 goto unregister_sor; 944 945 err = platform_driver_register(&tegra_dpaux_driver); 946 if (err < 0) 947 goto unregister_hdmi; 948 949 err = platform_driver_register(&tegra_gr2d_driver); 950 if (err < 0) 951 goto unregister_dpaux; 952 953 err = platform_driver_register(&tegra_gr3d_driver); 954 if (err < 0) 955 goto unregister_gr2d; 956 957 return 0; 958 959 unregister_gr2d: 960 platform_driver_unregister(&tegra_gr2d_driver); 961 unregister_dpaux: 962 platform_driver_unregister(&tegra_dpaux_driver); 963 unregister_hdmi: 964 platform_driver_unregister(&tegra_hdmi_driver); 965 unregister_sor: 966 platform_driver_unregister(&tegra_sor_driver); 967 unregister_dsi: 968 platform_driver_unregister(&tegra_dsi_driver); 969 unregister_dc: 970 platform_driver_unregister(&tegra_dc_driver); 971 unregister_host1x: 972 host1x_driver_unregister(&host1x_drm_driver); 973 return err; 974 } 975 module_init(host1x_drm_init); 976 977 static void __exit host1x_drm_exit(void) 978 { 979 platform_driver_unregister(&tegra_gr3d_driver); 980 platform_driver_unregister(&tegra_gr2d_driver); 981 platform_driver_unregister(&tegra_dpaux_driver); 982 platform_driver_unregister(&tegra_hdmi_driver); 983 platform_driver_unregister(&tegra_sor_driver); 984 platform_driver_unregister(&tegra_dsi_driver); 985 platform_driver_unregister(&tegra_dc_driver); 986 host1x_driver_unregister(&host1x_drm_driver); 987 } 988 module_exit(host1x_drm_exit); 989 990 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); 991 MODULE_DESCRIPTION("NVIDIA Tegra DRM driver"); 992 MODULE_LICENSE("GPL v2"); 993