From: Matthijs van Duin matthijsvanduin@gmail.com
--- drivers/gpu/drm/omapdrm/omap_gem.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 6cf190156dcf..670845b19e49 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -396,6 +396,7 @@ static int fault_1d(struct drm_gem_object *obj, return vm_insert_mixed(vma, vmf->address, __pfn_to_pfn_t(pfn, PFN_DEV)); }
+#if 0 /* Special handling for the case of faulting in 2d tiled buffers */ static int fault_2d(struct drm_gem_object *obj, struct vm_area_struct *vma, struct vm_fault *vmf) @@ -497,6 +498,7 @@ static int fault_2d(struct drm_gem_object *obj,
return 0; } +#endif
/** * omap_gem_fault - pagefault handler for GEM objects @@ -536,7 +538,7 @@ int omap_gem_fault(struct vm_fault *vmf) */
if (omap_obj->flags & OMAP_BO_TILED) - ret = fault_2d(obj, vma, vmf); + ret = -EFAULT; //fault_2d(obj, vma, vmf); else ret = fault_1d(obj, vma, vmf);
@@ -579,8 +581,10 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj, { struct omap_gem_object *omap_obj = to_omap_bo(obj);
- vma->vm_flags &= ~VM_PFNMAP; - vma->vm_flags |= VM_MIXEDMAP; + if (!(omap_obj->flags & OMAP_BO_TILED)) { + vma->vm_flags &= ~VM_PFNMAP; + vma->vm_flags |= VM_MIXEDMAP; + }
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
@@ -613,6 +617,25 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj, vma->vm_file = get_file(obj->filp); }
+ if (omap_obj->flags & OMAP_BO_TILED) { + const enum tiler_fmt fmt = gem2fmt(omap_obj->flags); + const uint vstride = tiler_vsize(fmt, omap_obj->width, 1); + const uint pstride = tiler_stride(fmt, 0) >> PAGE_SHIFT; + unsigned long vaddr = vma->vm_start; + unsigned long pfn = omap_obj->dma_addr >> PAGE_SHIFT; + uint i; + int ret = 0; + for (i = 0; i < omap_obj->height; i++) { + ret = remap_pfn_range(vma, vaddr, pfn, vstride, + vma->vm_page_prot); + if (ret) + break; + vaddr += vstride; + pfn += pstride; + } + return ret; + } + return 0; }