aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index f433eb7533a9..eae064a3ee30 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -34,6 +34,7 @@
34#include "exynos_drm_drv.h" 34#include "exynos_drm_drv.h"
35#include "exynos_drm_fb.h" 35#include "exynos_drm_fb.h"
36#include "exynos_drm_gem.h" 36#include "exynos_drm_gem.h"
37#include "exynos_drm_iommu.h"
37 38
38#define MAX_CONNECTOR 4 39#define MAX_CONNECTOR 4
39#define PREFERRED_BPP 32 40#define PREFERRED_BPP 32
@@ -111,9 +112,18 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
111 112
112 /* map pages with kernel virtual space. */ 113 /* map pages with kernel virtual space. */
113 if (!buffer->kvaddr) { 114 if (!buffer->kvaddr) {
114 unsigned int nr_pages = buffer->size >> PAGE_SHIFT; 115 if (is_drm_iommu_supported(dev)) {
115 buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, 116 unsigned int nr_pages = buffer->size >> PAGE_SHIFT;
117
118 buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP,
116 pgprot_writecombine(PAGE_KERNEL)); 119 pgprot_writecombine(PAGE_KERNEL));
120 } else {
121 phys_addr_t dma_addr = buffer->dma_addr;
122 if (dma_addr)
123 buffer->kvaddr = phys_to_virt(dma_addr);
124 else
125 buffer->kvaddr = (void __iomem *)NULL;
126 }
117 if (!buffer->kvaddr) { 127 if (!buffer->kvaddr) {
118 DRM_ERROR("failed to map pages to kernel space.\n"); 128 DRM_ERROR("failed to map pages to kernel space.\n");
119 return -EIO; 129 return -EIO;
@@ -128,8 +138,12 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
128 138
129 dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; 139 dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
130 fbi->screen_base = buffer->kvaddr + offset; 140 fbi->screen_base = buffer->kvaddr + offset;
131 fbi->fix.smem_start = (unsigned long) 141 if (is_drm_iommu_supported(dev))
142 fbi->fix.smem_start = (unsigned long)
132 (page_to_phys(sg_page(buffer->sgt->sgl)) + offset); 143 (page_to_phys(sg_page(buffer->sgt->sgl)) + offset);
144 else
145 fbi->fix.smem_start = (unsigned long)buffer->dma_addr;
146
133 fbi->screen_size = size; 147 fbi->screen_size = size;
134 fbi->fix.smem_len = size; 148 fbi->fix.smem_len = size;
135 149
@@ -320,7 +334,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev,
320 struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj; 334 struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj;
321 struct drm_framebuffer *fb; 335 struct drm_framebuffer *fb;
322 336
323 if (exynos_gem_obj->buffer->kvaddr) 337 if (is_drm_iommu_supported(dev) && exynos_gem_obj->buffer->kvaddr)
324 vunmap(exynos_gem_obj->buffer->kvaddr); 338 vunmap(exynos_gem_obj->buffer->kvaddr);
325 339
326 /* release drm framebuffer and real buffer */ 340 /* release drm framebuffer and real buffer */