drm: exynos: add support for prime vmap to exynos gem
authorMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 29 Mar 2018 10:35:51 +0000 (12:35 +0200)
committerJunghoon Kim <jhoon20.kim@samsung.com>
Thu, 14 Feb 2019 05:56:55 +0000 (14:56 +0900)
Change-Id: I9399ba024f2cc6e61c3b463071aef700ad4c9bed
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h

index 11cc01b..ce5fd30 100644 (file)
@@ -119,6 +119,12 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
        DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
                        (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
 
+       WARN_ON(exynos_gem->kvmap_count != 0);
+       if (exynos_gem->kvaddr) {
+               vunmap(exynos_gem->kvaddr);
+               exynos_gem->kvaddr = NULL;
+       }
+
        dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
                        (dma_addr_t)exynos_gem->dma_addr,
                        exynos_gem->dma_attrs);
@@ -587,12 +593,27 @@ err:
 
 void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj)
 {
-       return NULL;
+       struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
+       int nr_pages = exynos_gem->size >> PAGE_SHIFT;
+
+       if (!exynos_gem->kvaddr) {
+               exynos_gem->kvaddr = (void __iomem *) vmap(exynos_gem->pages,
+                       nr_pages, VM_MAP,
+                       pgprot_writecombine(PAGE_KERNEL));
+               if (!exynos_gem->kvaddr) {
+                       DRM_ERROR("failed to map pages to kernel space.\n");
+                       return ERR_PTR(-EIO);
+               }
+       }
+       exynos_gem->kvmap_count++;
+       return exynos_gem->kvaddr;
 }
 
 void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
 {
-       /* Nothing to do */
+       struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
+
+       WARN_ON(--exynos_gem->kvmap_count < 0);
 }
 
 int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
index 5a4c7de..c1e08e4 100644 (file)
@@ -49,6 +49,7 @@ struct exynos_drm_gem {
        unsigned long           size;
        void                    *cookie;
        void __iomem            *kvaddr;
+       unsigned int            kvmap_count;
        dma_addr_t              dma_addr;
        unsigned long           dma_attrs;
        struct page             **pages;