diff options
author | Inki Dae <inki.dae@samsung.com> | 2012-12-21 17:59:20 +0900 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2013-01-04 15:54:32 +0900 |
commit | c704f1b47d6cb4b61b2e120030088c2a7cefcc13 (patch) | |
tree | 9d0b313110b6dda6e7b622d50fc54b54dcca9fbe /drivers/gpu/drm | |
parent | f4fd9bd4863ebbccbcef113c03b9b628a8242a64 (diff) |
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 <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu/drm')
-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 f433eb7533a..eae064a3ee3 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 */ |