From c704f1b47d6cb4b61b2e120030088c2a7cefcc13 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Fri, 21 Dec 2012 17:59:20 +0900 Subject: [PATCH] drm/exynos: consider no iommu support to console framebuffer This patch considers no iommu support to kernel space mapping of console framebuffer. Without iommu, we get physical address instead of device address after dma_alloc_attrs function is called. So we should consider the case without iommu when it maps console framebuffer with kernel space. Changelog v2: - calll vunmap function only with iommu support. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 22 ++++++++++++++++++---- 1 file 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 @@ #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" +#include "exynos_drm_iommu.h" #define MAX_CONNECTOR 4 #define PREFERRED_BPP 32 @@ -111,9 +112,18 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, /* map pages with kernel virtual space. */ if (!buffer->kvaddr) { - unsigned int nr_pages = buffer->size >> PAGE_SHIFT; - buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, + if (is_drm_iommu_supported(dev)) { + unsigned int nr_pages = buffer->size >> PAGE_SHIFT; + + buffer->kvaddr = 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 = 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; @@ -128,8 +138,12 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; fbi->screen_base = buffer->kvaddr + offset; - fbi->fix.smem_start = (unsigned long) + if (is_drm_iommu_supported(dev)) + fbi->fix.smem_start = (unsigned long) (page_to_phys(sg_page(buffer->sgt->sgl)) + offset); + else + fbi->fix.smem_start = (unsigned long)buffer->dma_addr; + fbi->screen_size = size; fbi->fix.smem_len = size; @@ -320,7 +334,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 (exynos_gem_obj->buffer->kvaddr) + if (is_drm_iommu_supported(dev) && exynos_gem_obj->buffer->kvaddr) vunmap(exynos_gem_obj->buffer->kvaddr); /* release drm framebuffer and real buffer */ -- 2.34.1