From: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx> Move the code which sets up and tears down the MMU mappings (iow, allocates a node in the drm_mm, and then calls the iommu to setup the actual mapping, and the reverse) into etnaviv_mmu.c Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx> --- drivers/staging/etnaviv/etnaviv_gem.c | 33 ++++----------------------- drivers/staging/etnaviv/etnaviv_mmu.c | 43 +++++++++++++++++++++++++++++++++++ drivers/staging/etnaviv/etnaviv_mmu.h | 6 +++++ 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/drivers/staging/etnaviv/etnaviv_gem.c b/drivers/staging/etnaviv/etnaviv_gem.c index 647815e4f1ba..ab7c6db4ec10 100644 --- a/drivers/staging/etnaviv/etnaviv_gem.c +++ b/drivers/staging/etnaviv/etnaviv_gem.c @@ -278,32 +278,12 @@ int etnaviv_gem_get_iova_locked(struct etnaviv_gpu *gpu, struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); int ret = 0; - if (!etnaviv_obj->iova && !(etnaviv_obj->flags & ETNA_BO_CMDSTREAM)) { - struct etnaviv_drm_private *priv = obj->dev->dev_private; - struct etnaviv_iommu *mmu = priv->mmu; + if (!etnaviv_obj->iova && !(etnaviv_obj->flags & ETNA_BO_CMDSTREAM)) { struct page **pages = etnaviv_gem_get_pages(etnaviv_obj); - uint32_t offset; - struct drm_mm_node *node = NULL; - if (IS_ERR(pages)) return PTR_ERR(pages); - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - - ret = drm_mm_insert_node(&mmu->mm, node, obj->size, 0, - DRM_MM_SEARCH_DEFAULT); - - if (!ret) { - offset = node->start; - etnaviv_obj->iova = offset; - etnaviv_obj->gpu_vram_node = node; - - ret = etnaviv_iommu_map(mmu, offset, etnaviv_obj->sgt, - obj->size, IOMMU_READ | IOMMU_WRITE); - } else - kfree(node); + ret = etnaviv_iommu_map_gem(gpu->mmu, etnaviv_obj); } if (!ret) @@ -531,13 +511,8 @@ static void etnaviv_free_obj(struct drm_gem_object *obj) struct etnaviv_drm_private *priv = obj->dev->dev_private; struct etnaviv_iommu *mmu = priv->mmu; - if (mmu && etnaviv_obj->iova) { - uint32_t offset = etnaviv_obj->gpu_vram_node->start; - - etnaviv_iommu_unmap(mmu, offset, etnaviv_obj->sgt, obj->size); - drm_mm_remove_node(etnaviv_obj->gpu_vram_node); - kfree(etnaviv_obj->gpu_vram_node); - } + if (mmu) + etnaviv_iommu_unmap_gem(mmu, etnaviv_obj); } static void etnaviv_gem_shmem_release(struct etnaviv_gem_object *etnaviv_obj) diff --git a/drivers/staging/etnaviv/etnaviv_mmu.c b/drivers/staging/etnaviv/etnaviv_mmu.c index 51d91e3d30ed..2effe75cb154 100644 --- a/drivers/staging/etnaviv/etnaviv_mmu.c +++ b/drivers/staging/etnaviv/etnaviv_mmu.c @@ -16,6 +16,7 @@ */ #include "etnaviv_drv.h" +#include "etnaviv_gem.h" #include "etnaviv_mmu.h" static int etnaviv_fault_handler(struct iommu_domain *iommu, struct device *dev, @@ -90,6 +91,48 @@ int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, uint32_t iova, return 0; } +int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu, + struct etnaviv_gem_object *etnaviv_obj) +{ + struct sg_table *sgt = etnaviv_obj->sgt; + uint32_t offset; + struct drm_mm_node *node = NULL; + int ret; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return -ENOMEM; + + ret = drm_mm_insert_node(&mmu->mm, node, etnaviv_obj->base.size, 0, + DRM_MM_SEARCH_DEFAULT); + + if (!ret) { + offset = node->start; + etnaviv_obj->iova = offset; + etnaviv_obj->gpu_vram_node = node; + + ret = etnaviv_iommu_map(mmu, offset, sgt, + etnaviv_obj->base.size, + IOMMU_READ | IOMMU_WRITE); + } else + kfree(node); + + return ret; +} + +void etnaviv_iommu_unmap_gem(struct etnaviv_iommu *mmu, + struct etnaviv_gem_object *etnaviv_obj) +{ + if (etnaviv_obj->iova) { + uint32_t offset = etnaviv_obj->gpu_vram_node->start; + + etnaviv_iommu_unmap(mmu, offset, etnaviv_obj->sgt, + etnaviv_obj->base.size); + drm_mm_remove_node(etnaviv_obj->gpu_vram_node); + kfree(etnaviv_obj->gpu_vram_node); + } +} + void etnaviv_iommu_destroy(struct etnaviv_iommu *mmu) { drm_mm_takedown(&mmu->mm); diff --git a/drivers/staging/etnaviv/etnaviv_mmu.h b/drivers/staging/etnaviv/etnaviv_mmu.h index 1adcc3ab4ebc..262c4e26e901 100644 --- a/drivers/staging/etnaviv/etnaviv_mmu.h +++ b/drivers/staging/etnaviv/etnaviv_mmu.h @@ -29,12 +29,18 @@ struct etnaviv_iommu { bool need_flush; }; +struct etnaviv_gem_object; + int etnaviv_iommu_attach(struct etnaviv_iommu *iommu, const char **names, int cnt); int etnaviv_iommu_map(struct etnaviv_iommu *iommu, uint32_t iova, struct sg_table *sgt, unsigned len, int prot); int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, uint32_t iova, struct sg_table *sgt, unsigned len); +int etnaviv_iommu_map_gem(struct etnaviv_iommu *mmu, + struct etnaviv_gem_object *etnaviv_obj); +void etnaviv_iommu_unmap_gem(struct etnaviv_iommu *mmu, + struct etnaviv_gem_object *etnaviv_obj); void etnaviv_iommu_destroy(struct etnaviv_iommu *iommu); struct etnaviv_iommu *etnaviv_iommu_new(struct drm_device *dev, -- 2.1.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel