summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
diff options
context:
space:
mode:
authorCarlo Caione <carlo@caione.org>2015-02-04 12:23:19 +0300
committerInki Dae <inki.dae@samsung.com>2015-02-07 10:38:41 +0300
commita5d7ac30fa9ffa923e3603309692a36e3b3b3ae1 (patch)
tree6306790667cadc1cc34c5a5a5b39e7385863259a /drivers/gpu/drm/exynos/exynos_drm_fbdev.c
parent129046c6ecb662e902a241bbbcb1da4206986370 (diff)
downloadlinux-a5d7ac30fa9ffa923e3603309692a36e3b3b3ae1.tar.xz
drm/exynos: fix DMA_ATTR_NO_KERNEL_MAPPING usage
The Exynos DRM driver doesn't follow the correct API when dealing with dma_{alloc, mmap, free}_attrs functions and the DMA_ATTR_NO_KERNEL_MAPPING attribute. When a IOMMU is not available and the DMA_ATTR_NO_KERNEL_MAPPING is used, the driver should use the pointer returned by dma_alloc_attr() as a cookie. The Exynos DRM driver directly uses the non-requested virtual kernel address returned by the DMA mapping subsystem. This just works now because the non-IOMMU codepath doesn't obey DMA_ATTR_NO_KERNEL_MAPPING but we need to fix it before fixing the DMA layer. Signed-off-by: Carlo Caione <carlo@caione.org> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fbdev.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c29
1 files changed, 9 insertions, 20 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index e12ea90c6237..84f8dfe1c5ec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -79,9 +79,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
struct drm_framebuffer *fb)
{
struct fb_info *fbi = helper->fbdev;
- struct drm_device *dev = helper->dev;
struct exynos_drm_gem_buf *buffer;
unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
+ unsigned int nr_pages;
unsigned long offset;
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
@@ -94,25 +94,14 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
return -EFAULT;
}
- /* map pages with kernel virtual space. */
+ nr_pages = buffer->size >> PAGE_SHIFT;
+
+ buffer->kvaddr = (void __iomem *) vmap(buffer->pages,
+ nr_pages, VM_MAP,
+ pgprot_writecombine(PAGE_KERNEL));
if (!buffer->kvaddr) {
- if (is_drm_iommu_supported(dev)) {
- unsigned int nr_pages = buffer->size >> PAGE_SHIFT;
-
- buffer->kvaddr = (void __iomem *) vmap(buffer->pages,
- nr_pages, VM_MAP,
- pgprot_writecombine(PAGE_KERNEL));
- } else {
- phys_addr_t dma_addr = buffer->dma_addr;
- if (dma_addr)
- buffer->kvaddr = (void __iomem *)phys_to_virt(dma_addr);
- else
- buffer->kvaddr = (void __iomem *)NULL;
- }
- if (!buffer->kvaddr) {
- DRM_ERROR("failed to map pages to kernel space.\n");
- return -EIO;
- }
+ DRM_ERROR("failed to map pages to kernel space.\n");
+ return -EIO;
}
/* buffer count to framebuffer always is 1 at booting time. */
@@ -313,7 +302,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev,
struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj;
struct drm_framebuffer *fb;
- if (is_drm_iommu_supported(dev) && exynos_gem_obj->buffer->kvaddr)
+ if (exynos_gem_obj->buffer->kvaddr)
vunmap(exynos_gem_obj->buffer->kvaddr);
/* release drm framebuffer and real buffer */