drm/rockchip: logo: add iommu map size for logo buffer iommu mapping
authorMark Yao <mark.yao@rock-chips.com>
Wed, 18 Jan 2017 04:50:40 +0000 (12:50 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 18 Jan 2017 07:47:57 +0000 (15:47 +0800)
Fix bug:
  iova 0x0(logo buffer) unmap fail:
    iommu: unaligned: iova 0x0 size 0xa5638 min_pagesz 0x1000
  then cause iova 0x0 mmap fail:
    iova: 0x0000000000000000 already mapped to 0x00000000f5c00000 cannot remap to phys: 0x00000000d6c6f000 prot: 0x3

Change-Id: I77443e9dba98aa6141aa44a42880b1cccc04043b
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
drivers/gpu/drm/rockchip/rockchip_drm_fb.c

index cbd133eb25aa171ae531d054da95f19d0eebd6b2..4c58306c606f68d8d7dc7c9683a51c7268b0d450 100644 (file)
@@ -162,8 +162,10 @@ static int init_loader_memory(struct drm_device *drm_dev)
 
                logo->dma_addr = logo->mm.start;
 
-               if (iommu_map_sg(private->domain, logo->dma_addr, sgt->sgl,
-                                sgt->nents, prot) < size) {
+               logo->iommu_map_size = iommu_map_sg(private->domain,
+                                                   logo->dma_addr, sgt->sgl,
+                                                   sgt->nents, prot);
+               if (logo->iommu_map_size < size) {
                        DRM_ERROR("failed to map buffer");
                        ret = -ENOMEM;
                        goto err_remove_node;
index 8ddc21eadc3930a289b0c2d540a0e66c916641bf..8a8d67381e74e4d5dd43527fbfb534a85d60b842 100644 (file)
@@ -102,6 +102,7 @@ struct rockchip_logo {
        dma_addr_t dma_addr;
        phys_addr_t start;
        phys_addr_t size;
+       size_t iommu_map_size;
        int count;
 };
 
index 7bb9e787bf41980781e5b6d8aa5ca61d3881f064..9b8d15b1e26778315cac048b5ff79bf70bba8473 100644 (file)
@@ -67,7 +67,7 @@ static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
 
                        if (private && private->domain) {
                                iommu_unmap(private->domain, logo->dma_addr,
-                                           logo->size);
+                                           logo->iommu_map_size);
                                drm_mm_remove_node(&logo->mm);
                        } else {
                                dma_unmap_sg(fb->dev->dev, logo->sgt->sgl,