void *rockchip_gem_prime_vmap(struct drm_gem_object *obj) { struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rk_obj->dma_attrs)) return NULL; return rk_obj->kvaddr; }
/* * rockchip_gem_free_object - (struct drm_driver)->gem_free_object callback * function */ void rockchip_gem_free_object(struct drm_gem_object *obj) { struct rockchip_gem_object *rk_obj; drm_gem_free_mmap_offset(obj); rk_obj = to_rockchip_obj(obj); rockchip_gem_free_buf(rk_obj); kfree(rk_obj); }
int rockchip_gem_mmap_buf(struct drm_gem_object *obj, struct vm_area_struct *vma) { struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); struct drm_device *drm = obj->dev; unsigned long vm_size; vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; vm_size = vma->vm_end - vma->vm_start; if (vm_size > obj->size) return -EINVAL; return dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, obj->size, &rk_obj->dma_attrs); }
static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { int ret; struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); struct drm_device *drm = obj->dev; /* * dma_alloc_attrs() allocated a struct page table for rk_obj, so clear * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap(). */ vma->vm_flags &= ~VM_PFNMAP; ret = dma_mmap_attrs(drm->dev, vma, rk_obj->kvaddr, rk_obj->dma_addr, obj->size, &rk_obj->dma_attrs); if (ret) drm_gem_vm_close(vma); return ret; }
/* * Allocate a sg_table for this GEM object. * Note: Both the table's contents, and the sg_table itself must be freed by * the caller. * Returns a pointer to the newly allocated sg_table, or an ERR_PTR() error. */ struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj) { struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); struct drm_device *drm = obj->dev; struct sg_table *sgt; int ret; sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) return ERR_PTR(-ENOMEM); ret = dma_get_sgtable_attrs(drm->dev, sgt, rk_obj->kvaddr, rk_obj->dma_addr, obj->size, &rk_obj->dma_attrs); if (ret) { DRM_ERROR("failed to allocate sgt, %d\n", ret); kfree(sgt); return ERR_PTR(ret); } return sgt; }