aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/Makefile1
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c15
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h13
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c120
-rw-r--r--drivers/gpu/drm/msm/msm_gem_prime.c56
5 files changed, 179 insertions, 26 deletions
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index e17914889e54..e5fa12b0d21e 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -21,6 +21,7 @@ msm-y := \
21 msm_drv.o \ 21 msm_drv.o \
22 msm_fb.o \ 22 msm_fb.o \
23 msm_gem.o \ 23 msm_gem.o \
24 msm_gem_prime.o \
24 msm_gem_submit.o \ 25 msm_gem_submit.o \
25 msm_gpu.o \ 26 msm_gpu.o \
26 msm_ringbuffer.o 27 msm_ringbuffer.o
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index b3a2f1629041..cfeebdd911dd 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -680,7 +680,10 @@ static const struct file_operations fops = {
680}; 680};
681 681
682static struct drm_driver msm_driver = { 682static struct drm_driver msm_driver = {
683 .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, 683 .driver_features = DRIVER_HAVE_IRQ |
684 DRIVER_GEM |
685 DRIVER_PRIME |
686 DRIVER_MODESET,
684 .load = msm_load, 687 .load = msm_load,
685 .unload = msm_unload, 688 .unload = msm_unload,
686 .open = msm_open, 689 .open = msm_open,
@@ -698,6 +701,16 @@ static struct drm_driver msm_driver = {
698 .dumb_create = msm_gem_dumb_create, 701 .dumb_create = msm_gem_dumb_create,
699 .dumb_map_offset = msm_gem_dumb_map_offset, 702 .dumb_map_offset = msm_gem_dumb_map_offset,
700 .dumb_destroy = drm_gem_dumb_destroy, 703 .dumb_destroy = drm_gem_dumb_destroy,
704 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
705 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
706 .gem_prime_export = drm_gem_prime_export,
707 .gem_prime_import = drm_gem_prime_import,
708 .gem_prime_pin = msm_gem_prime_pin,
709 .gem_prime_unpin = msm_gem_prime_unpin,
710 .gem_prime_get_sg_table = msm_gem_prime_get_sg_table,
711 .gem_prime_import_sg_table = msm_gem_prime_import_sg_table,
712 .gem_prime_vmap = msm_gem_prime_vmap,
713 .gem_prime_vunmap = msm_gem_prime_vunmap,
701#ifdef CONFIG_DEBUG_FS 714#ifdef CONFIG_DEBUG_FS
702 .debugfs_init = msm_debugfs_init, 715 .debugfs_init = msm_debugfs_init,
703 .debugfs_cleanup = msm_debugfs_cleanup, 716 .debugfs_cleanup = msm_debugfs_cleanup,
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index df8f1d084bc1..9ce90c267ef8 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -141,13 +141,20 @@ uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
141int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, 141int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
142 uint32_t *iova); 142 uint32_t *iova);
143int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova); 143int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova);
144struct page **msm_gem_get_pages(struct drm_gem_object *obj);
145void msm_gem_put_pages(struct drm_gem_object *obj);
144void msm_gem_put_iova(struct drm_gem_object *obj, int id); 146void msm_gem_put_iova(struct drm_gem_object *obj, int id);
145int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, 147int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
146 struct drm_mode_create_dumb *args); 148 struct drm_mode_create_dumb *args);
147int msm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
148 uint32_t handle);
149int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, 149int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
150 uint32_t handle, uint64_t *offset); 150 uint32_t handle, uint64_t *offset);
151struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
152void *msm_gem_prime_vmap(struct drm_gem_object *obj);
153void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
154struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
155 size_t size, struct sg_table *sg);
156int msm_gem_prime_pin(struct drm_gem_object *obj);
157void msm_gem_prime_unpin(struct drm_gem_object *obj);
151void *msm_gem_vaddr_locked(struct drm_gem_object *obj); 158void *msm_gem_vaddr_locked(struct drm_gem_object *obj);
152void *msm_gem_vaddr(struct drm_gem_object *obj); 159void *msm_gem_vaddr(struct drm_gem_object *obj);
153int msm_gem_queue_inactive_work(struct drm_gem_object *obj, 160int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
@@ -163,6 +170,8 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
163 uint32_t size, uint32_t flags, uint32_t *handle); 170 uint32_t size, uint32_t flags, uint32_t *handle);
164struct drm_gem_object *msm_gem_new(struct drm_device *dev, 171struct drm_gem_object *msm_gem_new(struct drm_device *dev,
165 uint32_t size, uint32_t flags); 172 uint32_t size, uint32_t flags);
173struct drm_gem_object *msm_gem_import(struct drm_device *dev,
174 uint32_t size, struct sg_table *sgt);
166 175
167struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane); 176struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
168const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb); 177const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 2bae46c66a30..ea2c96f9459b 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/shmem_fs.h> 19#include <linux/shmem_fs.h>
20#include <linux/dma-buf.h>
20 21
21#include "msm_drv.h" 22#include "msm_drv.h"
22#include "msm_gem.h" 23#include "msm_gem.h"
@@ -77,6 +78,21 @@ static void put_pages(struct drm_gem_object *obj)
77 } 78 }
78} 79}
79 80
81struct page **msm_gem_get_pages(struct drm_gem_object *obj)
82{
83 struct drm_device *dev = obj->dev;
84 struct page **p;
85 mutex_lock(&dev->struct_mutex);
86 p = get_pages(obj);
87 mutex_unlock(&dev->struct_mutex);
88 return p;
89}
90
91void msm_gem_put_pages(struct drm_gem_object *obj)
92{
93 /* when we start tracking the pin count, then do something here */
94}
95
80int msm_gem_mmap_obj(struct drm_gem_object *obj, 96int msm_gem_mmap_obj(struct drm_gem_object *obj,
81 struct vm_area_struct *vma) 97 struct vm_area_struct *vma)
82{ 98{
@@ -510,10 +526,21 @@ void msm_gem_free_object(struct drm_gem_object *obj)
510 526
511 drm_gem_free_mmap_offset(obj); 527 drm_gem_free_mmap_offset(obj);
512 528
513 if (msm_obj->vaddr) 529 if (obj->import_attach) {
514 vunmap(msm_obj->vaddr); 530 if (msm_obj->vaddr)
531 dma_buf_vunmap(obj->import_attach->dmabuf, msm_obj->vaddr);
532
533 /* Don't drop the pages for imported dmabuf, as they are not
534 * ours, just free the array we allocated:
535 */
536 if (msm_obj->pages)
537 drm_free_large(msm_obj->pages);
515 538
516 put_pages(obj); 539 } else {
540 if (msm_obj->vaddr)
541 vunmap(msm_obj->vaddr);
542 put_pages(obj);
543 }
517 544
518 if (msm_obj->resv == &msm_obj->_resv) 545 if (msm_obj->resv == &msm_obj->_resv)
519 reservation_object_fini(msm_obj->resv); 546 reservation_object_fini(msm_obj->resv);
@@ -549,17 +576,12 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
549 return ret; 576 return ret;
550} 577}
551 578
552struct drm_gem_object *msm_gem_new(struct drm_device *dev, 579static int msm_gem_new_impl(struct drm_device *dev,
553 uint32_t size, uint32_t flags) 580 uint32_t size, uint32_t flags,
581 struct drm_gem_object **obj)
554{ 582{
555 struct msm_drm_private *priv = dev->dev_private; 583 struct msm_drm_private *priv = dev->dev_private;
556 struct msm_gem_object *msm_obj; 584 struct msm_gem_object *msm_obj;
557 struct drm_gem_object *obj = NULL;
558 int ret;
559
560 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
561
562 size = PAGE_ALIGN(size);
563 585
564 switch (flags & MSM_BO_CACHE_MASK) { 586 switch (flags & MSM_BO_CACHE_MASK) {
565 case MSM_BO_UNCACHED: 587 case MSM_BO_UNCACHED:
@@ -569,21 +591,12 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
569 default: 591 default:
570 dev_err(dev->dev, "invalid cache flag: %x\n", 592 dev_err(dev->dev, "invalid cache flag: %x\n",
571 (flags & MSM_BO_CACHE_MASK)); 593 (flags & MSM_BO_CACHE_MASK));
572 ret = -EINVAL; 594 return -EINVAL;
573 goto fail;
574 } 595 }
575 596
576 msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL); 597 msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL);
577 if (!msm_obj) { 598 if (!msm_obj)
578 ret = -ENOMEM; 599 return -ENOMEM;
579 goto fail;
580 }
581
582 obj = &msm_obj->base;
583
584 ret = drm_gem_object_init(dev, obj, size);
585 if (ret)
586 goto fail;
587 600
588 msm_obj->flags = flags; 601 msm_obj->flags = flags;
589 602
@@ -594,6 +607,67 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
594 INIT_LIST_HEAD(&msm_obj->inactive_work); 607 INIT_LIST_HEAD(&msm_obj->inactive_work);
595 list_add_tail(&msm_obj->mm_list, &priv->inactive_list); 608 list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
596 609
610 *obj = &msm_obj->base;
611
612 return 0;
613}
614
615struct drm_gem_object *msm_gem_new(struct drm_device *dev,
616 uint32_t size, uint32_t flags)
617{
618 struct drm_gem_object *obj;
619 int ret;
620
621 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
622
623 size = PAGE_ALIGN(size);
624
625 ret = msm_gem_new_impl(dev, size, flags, &obj);
626 if (ret)
627 goto fail;
628
629 ret = drm_gem_object_init(dev, obj, size);
630 if (ret)
631 goto fail;
632
633 return obj;
634
635fail:
636 if (obj)
637 drm_gem_object_unreference_unlocked(obj);
638
639 return ERR_PTR(ret);
640}
641
642struct drm_gem_object *msm_gem_import(struct drm_device *dev,
643 uint32_t size, struct sg_table *sgt)
644{
645 struct msm_gem_object *msm_obj;
646 struct drm_gem_object *obj;
647 int ret, npages;
648
649 size = PAGE_ALIGN(size);
650
651 ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj);
652 if (ret)
653 goto fail;
654
655 drm_gem_private_object_init(dev, obj, size);
656
657 npages = size / PAGE_SIZE;
658
659 msm_obj = to_msm_bo(obj);
660 msm_obj->sgt = sgt;
661 msm_obj->pages = drm_malloc_ab(npages, sizeof(struct page *));
662 if (!msm_obj->pages) {
663 ret = -ENOMEM;
664 goto fail;
665 }
666
667 ret = drm_prime_sg_to_page_addr_arrays(sgt, msm_obj->pages, NULL, npages);
668 if (ret)
669 goto fail;
670
597 return obj; 671 return obj;
598 672
599fail: 673fail:
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c
new file mode 100644
index 000000000000..d48f9fc5129b
--- /dev/null
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -0,0 +1,56 @@
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_gem.h"
20
21
22struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
23{
24 struct msm_gem_object *msm_obj = to_msm_bo(obj);
25 BUG_ON(!msm_obj->sgt); /* should have already pinned! */
26 return msm_obj->sgt;
27}
28
29void *msm_gem_prime_vmap(struct drm_gem_object *obj)
30{
31 return msm_gem_vaddr(obj);
32}
33
34void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
35{
36 /* TODO msm_gem_vunmap() */
37}
38
39struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
40 size_t size, struct sg_table *sg)
41{
42 return msm_gem_import(dev, size, sg);
43}
44
45int msm_gem_prime_pin(struct drm_gem_object *obj)
46{
47 if (!obj->import_attach)
48 msm_gem_get_pages(obj);
49 return 0;
50}
51
52void msm_gem_prime_unpin(struct drm_gem_object *obj)
53{
54 if (!obj->import_attach)
55 msm_gem_put_pages(obj);
56}