if (exynos_gem->dma_addr) {
DRM_DEV_DEBUG_KMS(to_dma_dev(dev), "already allocated.\n"); return 0;
}
/* * if EXYNOS_BO_CONTIG, fully physically contiguous memory * region will be allocated else physically contiguous * as possible.
*/ if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
attr |= DMA_ATTR_FORCE_CONTIGUOUS;
/* * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping * else cachable mapping.
*/ if (exynos_gem->flags & EXYNOS_BO_WC ||
!(exynos_gem->flags & EXYNOS_BO_CACHABLE))
attr |= DMA_ATTR_WRITE_COMBINE;
/* * allocate a id of idr table where the obj is registered * and handle has the id what user can see.
*/
ret = drm_gem_handle_create(file_priv, obj, handle); if (ret) return ret;
/* * do not release memory region from exporter. * * the region will be released by exporter * once dmabuf's refcount becomes 0.
*/ if (obj->import_attach)
drm_prime_gem_destroy(obj, exynos_gem->sgt); else
exynos_drm_free_buf(exynos_gem);
/* release file pointer to gem object. */
drm_gem_object_release(obj);
exynos_gem = exynos_drm_gem_init(dev, size); if (IS_ERR(exynos_gem)) return exynos_gem;
if (!is_drm_iommu_supported(dev) && (flags & EXYNOS_BO_NONCONTIG)) { /* * when no IOMMU is available, all allocated buffers are * contiguous anyway, so drop EXYNOS_BO_NONCONTIG flag
*/
flags &= ~EXYNOS_BO_NONCONTIG;
DRM_WARN("Non-contiguous allocation is not supported without IOMMU, falling back to contiguous buffer\n");
}
/* set memory type and cache attribute from user side. */
exynos_gem->flags = flags;
ret = exynos_drm_alloc_buf(exynos_gem, kvmap); if (ret < 0) {
drm_gem_object_release(&exynos_gem->base);
kfree(exynos_gem); return ERR_PTR(ret);
}
return exynos_gem;
}
int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{ struct drm_exynos_gem_create *args = data; struct exynos_drm_gem *exynos_gem; int ret;
exynos_gem = exynos_drm_gem_create(dev, args->flags, args->size, false); if (IS_ERR(exynos_gem)) return PTR_ERR(exynos_gem);
ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
&args->handle); if (ret) {
exynos_drm_gem_destroy(exynos_gem); return ret;
}
/* check if the entries in the sg_table are contiguous */ if (drm_prime_get_contiguous_size(sgt) < attach->dmabuf->size) {
DRM_ERROR("buffer chunks must be mapped contiguously"); return ERR_PTR(-EINVAL);
}
exynos_gem = exynos_drm_gem_init(dev, attach->dmabuf->size); if (IS_ERR(exynos_gem)) return ERR_CAST(exynos_gem);
/* * Buffer has been mapped as contiguous into DMA address space, * but if there is IOMMU, it can be either CONTIG or NONCONTIG. * We assume a simplified logic below:
*/ if (is_drm_iommu_supported(dev))
exynos_gem->flags |= EXYNOS_BO_NONCONTIG; else
exynos_gem->flags |= EXYNOS_BO_CONTIG;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.