summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra/fb.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-06-26 21:41:53 +0200
committerThierry Reding <treding@nvidia.com>2014-11-13 16:14:48 +0100
commitdf06b759f2cf4690fa9991edb1504ba39932b2bb (patch)
tree0365d27fb82b94d4569c8b86dd775838bedc5ff1 /drivers/gpu/drm/tegra/fb.c
parentdrm/tegra: Fix error handling cleanup (diff)
downloadlinux-df06b759f2cf4690fa9991edb1504ba39932b2bb.tar.xz
linux-df06b759f2cf4690fa9991edb1504ba39932b2bb.zip
drm/tegra: Add IOMMU support
When an IOMMU device is available on the platform bus, allocate an IOMMU domain and attach the display controllers to it. The display controllers can then scan out non-contiguous buffers by mapping them through the IOMMU. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/fb.c')
-rw-r--r--drivers/gpu/drm/tegra/fb.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 0474241ac2a4..fab39eb2dae8 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -65,8 +65,12 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
for (i = 0; i < fb->num_planes; i++) {
struct tegra_bo *bo = fb->planes[i];
- if (bo)
+ if (bo) {
+ if (bo->pages && bo->vaddr)
+ vunmap(bo->vaddr);
+
drm_gem_object_unreference_unlocked(&bo->gem);
+ }
}
drm_framebuffer_cleanup(framebuffer);
@@ -254,6 +258,16 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
offset = info->var.xoffset * bytes_per_pixel +
info->var.yoffset * fb->pitches[0];
+ if (bo->pages) {
+ bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP,
+ pgprot_writecombine(PAGE_KERNEL));
+ if (!bo->vaddr) {
+ dev_err(drm->dev, "failed to vmap() framebuffer\n");
+ err = -ENOMEM;
+ goto destroy;
+ }
+ }
+
drm->mode_config.fb_base = (resource_size_t)bo->paddr;
info->screen_base = (void __iomem *)bo->vaddr + offset;
info->screen_size = size;