diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 22 |
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 */ |