[PATCH 8/8] etnaviv: remove IOMMU dependency

Philipp Zabel p.zabel at pengutronix.de
Mon Sep 18 18:33:41 UTC 2017


On Fri, 2017-09-15 at 19:04 +0200, Lucas Stach wrote:
> Using the IOMMU API to manage the internal GPU MMU has been an
> historical accident and it keeps getting in the way, as well as
> entangling the driver with the inner workings of the IOMMU
> subsystem.
> 
> Clean this up by removing the usage of iommu_domain, which is the
> last piece linking etnaviv to the IOMMU subsystem.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  drivers/gpu/drm/etnaviv/Kconfig            |  2 -
>  drivers/gpu/drm/etnaviv/etnaviv_drv.h      |  1 -
>  drivers/gpu/drm/etnaviv/etnaviv_iommu.c    | 71 +++++++++++++++----
> -----------
>  drivers/gpu/drm/etnaviv/etnaviv_iommu.h    |  6 ++-
>  drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c | 55 +++++++++++--------
> ----
>  drivers/gpu/drm/etnaviv/etnaviv_mmu.c      | 38 +++++++---------
>  drivers/gpu/drm/etnaviv/etnaviv_mmu.h      | 20 ++++++---
>  7 files changed, 93 insertions(+), 100 deletions(-)
> 
> diff --git a/drivers/gpu/drm/etnaviv/Kconfig
> b/drivers/gpu/drm/etnaviv/Kconfig
> index 71cee4e9fefb..b0a4ee27eb05 100644
> --- a/drivers/gpu/drm/etnaviv/Kconfig
> +++ b/drivers/gpu/drm/etnaviv/Kconfig
> @@ -7,8 +7,6 @@ config DRM_ETNAVIV
>  	select SHMEM
>  	select SYNC_FILE
>  	select TMPFS
> -	select IOMMU_API
> -	select IOMMU_SUPPORT
>  	select WANT_DEV_COREDUMP
>  	help
>  	  DRM driver for Vivante GPUs.
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> index 058389f93b69..d157d9379e68 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> @@ -26,7 +26,6 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/slab.h>
>  #include <linux/list.h>
> -#include <linux/iommu.h>
>  #include <linux/types.h>
>  #include <linux/sizes.h>
>  
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
> b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
> index 43a0508bdbd7..f0390842441a 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
> @@ -14,7 +14,6 @@
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> -#include <linux/iommu.h>
>  #include <linux/platform_device.h>
>  #include <linux/sizes.h>
>  #include <linux/slab.h>
> @@ -36,20 +35,21 @@ struct etnaviv_iommu_domain_pgtable {

Should this be renamed to etnaviv_iommuv2_domain_pgtable for
consistency?

>  	dma_addr_t paddr;
>  };
>  
> -struct etnaviv_iommu_domain {
> -	struct iommu_domain domain;
> +struct etnaviv_iommuv1_domain {
> +	struct etnaviv_iommu_domain base;
>  	struct device *dev;
>  	void *bad_page_cpu;
>  	dma_addr_t bad_page_dma;

Now that base is etnaviv specific, these three could be moved up into
etnaviv_iommu_domain.

>  	struct etnaviv_iommu_domain_pgtable pgtable;
>  };
>  
> -static struct etnaviv_iommu_domain *to_etnaviv_domain(struct
> iommu_domain *domain)
> +static struct etnaviv_iommuv1_domain *
> +to_etnaviv_domain(struct etnaviv_iommu_domain *domain)
>  {
> -	return container_of(domain, struct etnaviv_iommu_domain,
> domain);
> +	return container_of(domain, struct etnaviv_iommuv1_domain,
> base);
>  }
>  
> -static int __etnaviv_iommu_init(struct etnaviv_iommu_domain
> *etnaviv_domain)
> +static int __etnaviv_iommu_init(struct etnaviv_iommuv1_domain
> *etnaviv_domain)
>  {
>  	u32 *p;
>  	int ret, i;
> @@ -83,9 +83,10 @@ static int __etnaviv_iommu_init(struct
> etnaviv_iommu_domain *etnaviv_domain)
>  	return 0;
>  }
>  
> -static void etnaviv_domain_free(struct iommu_domain *domain)
> +static void etnaviv_iommuv1_domain_free(struct etnaviv_iommu_domain
> *domain)
>  {
> -	struct etnaviv_iommu_domain *etnaviv_domain =
> to_etnaviv_domain(domain);
> +	struct etnaviv_iommuv1_domain *etnaviv_domain =
> +			to_etnaviv_domain(domain);
>  
>  	dma_free_coherent(etnaviv_domain->dev, PT_SIZE,
>  			  etnaviv_domain->pgtable.pgtable,
> @@ -98,10 +99,11 @@ static void etnaviv_domain_free(struct
> iommu_domain *domain)
>  	kfree(etnaviv_domain);
>  }
>  
> -static int etnaviv_iommuv1_map(struct iommu_domain *domain, unsigned
> long iova,
> -	   phys_addr_t paddr, size_t size, int prot)
> +static int etnaviv_iommuv1_map(struct etnaviv_iommu_domain *domain,
> +			       unsigned long iova, phys_addr_t paddr,
> +			       size_t size, int prot)
>  {
> -	struct etnaviv_iommu_domain *etnaviv_domain =
> to_etnaviv_domain(domain);
> +	struct etnaviv_iommuv1_domain *etnaviv_domain =
> to_etnaviv_domain(domain);
>  	unsigned int index = (iova - GPU_MEM_START) / SZ_4K;
>  
>  	if (size != SZ_4K)
> @@ -112,10 +114,11 @@ static int etnaviv_iommuv1_map(struct
> iommu_domain *domain, unsigned long iova,
>  	return 0;
>  }
>  
> -static size_t etnaviv_iommuv1_unmap(struct iommu_domain *domain,
> +static size_t etnaviv_iommuv1_unmap(struct etnaviv_iommu_domain
> *domain,
>  	unsigned long iova, size_t size)
>  {
> -	struct etnaviv_iommu_domain *etnaviv_domain =
> to_etnaviv_domain(domain);
> +	struct etnaviv_iommuv1_domain *etnaviv_domain =
> +			to_etnaviv_domain(domain);
>  	unsigned int index = (iova - GPU_MEM_START) / SZ_4K;
>  
>  	if (size != SZ_4K)
> @@ -126,32 +129,22 @@ static size_t etnaviv_iommuv1_unmap(struct
> iommu_domain *domain,
>  	return SZ_4K;
>  }
>  
> -static size_t etnaviv_iommuv1_dump_size(struct iommu_domain *domain)
> +static size_t etnaviv_iommuv1_dump_size(struct etnaviv_iommu_domain
> *domain)
>  {
>  	return PT_SIZE;
>  }
>  
> -static void etnaviv_iommuv1_dump(struct iommu_domain *domain, void
> *buf)
> +static void etnaviv_iommuv1_dump(struct etnaviv_iommu_domain *domain,
> void *buf)
>  {
> -	struct etnaviv_iommu_domain *etnaviv_domain =
> to_etnaviv_domain(domain);
> +	struct etnaviv_iommuv1_domain *etnaviv_domain =
> +			to_etnaviv_domain(domain);
>  
>  	memcpy(buf, etnaviv_domain->pgtable.pgtable, PT_SIZE);
>  }
>  
> -static const struct etnaviv_iommu_ops etnaviv_iommu_ops = {
> -	.ops = {
> -		.domain_free = etnaviv_domain_free,
> -		.map = etnaviv_iommuv1_map,
> -		.unmap = etnaviv_iommuv1_unmap,
> -		.pgsize_bitmap = SZ_4K,
> -	},
> -	.dump_size = etnaviv_iommuv1_dump_size,
> -	.dump = etnaviv_iommuv1_dump,
> -};
> -
>  void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu)
>  {
> -	struct etnaviv_iommu_domain *etnaviv_domain =
> +	struct etnaviv_iommuv1_domain *etnaviv_domain =
>  			to_etnaviv_domain(gpu->mmu->domain);
>  	u32 pgtable;
>  
> @@ -172,9 +165,11 @@ void etnaviv_iommuv1_restore(struct etnaviv_gpu
> *gpu)
>  	gpu_write(gpu, VIVS_MC_MMU_RA_PAGE_TABLE, pgtable);
>  }
>  
> -struct iommu_domain *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu
> *gpu)
> +struct etnaviv_iommu_domain *
> +etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu)
>  {
> -	struct etnaviv_iommu_domain *etnaviv_domain;
> +	struct etnaviv_iommuv1_domain *etnaviv_domain;
> +	struct etnaviv_iommu_domain *domain;
>  	int ret;
>  
>  	etnaviv_domain = kzalloc(sizeof(*etnaviv_domain),
> GFP_KERNEL);
> @@ -183,17 +178,21 @@ struct iommu_domain
> *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu)
>  
>  	etnaviv_domain->dev = gpu->dev;
>  
> -	etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING;
> -	etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops;
> -	etnaviv_domain->domain.pgsize_bitmap = SZ_4K;
> -	etnaviv_domain->domain.geometry.aperture_start =
> GPU_MEM_START;
> -	etnaviv_domain->domain.geometry.aperture_end = GPU_MEM_START
> + PT_ENTRIES * SZ_4K - 1;
> +	domain = &etnaviv_domain->base;
> +
> +	domain->free = etnaviv_iommuv1_domain_free;
> +	domain->map = etnaviv_iommuv1_map;
> +	domain->unmap = etnaviv_iommuv1_unmap,
> +	domain->dump_size = etnaviv_iommuv1_dump_size;
> +	domain->dump = etnaviv_iommuv1_dump;
> +	domain->base = GPU_MEM_START;
> +	domain->size = PT_ENTRIES * SZ_4K;
>  
>  	ret = __etnaviv_iommu_init(etnaviv_domain);
>  	if (ret)
>  		goto out_free;
>  
> -	return &etnaviv_domain->domain;
> +	return &etnaviv_domain->base;
>  
>  out_free:
>  	kfree(etnaviv_domain);
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
> b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
> index 8b51e7c16feb..750bc7e796c7 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
> @@ -19,10 +19,12 @@
>  
>  struct etnaviv_gpu;

struct etnaviv_iommu_domain;

> -struct iommu_domain *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu
> *gpu);
> +struct etnaviv_iommu_domain *
> +etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu);

This is missing a declaration of struct etnaviv_iommu_domain.

>  void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu);
>  
> -struct iommu_domain *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu
> *gpu);
> +struct etnaviv_iommu_domain *
> +etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu);
>  void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu);
>  
>  #endif /* __ETNAVIV_IOMMU_H__ */
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
> b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
> index d794e8c0dd7e..c7437a59034e 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
> @@ -14,7 +14,6 @@
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> -#include <linux/iommu.h>
>  #include <linux/platform_device.h>
>  #include <linux/sizes.h>
>  #include <linux/slab.h>
> @@ -40,7 +39,7 @@
>  #define MMUv2_MAX_STLB_ENTRIES		1024
>  
>  struct etnaviv_iommuv2_domain {
> -	struct iommu_domain domain;
> +	struct etnaviv_iommu_domain base;
>  	struct device *dev;
>  	void *bad_page_cpu;
>  	dma_addr_t bad_page_dma;
> @@ -52,13 +51,15 @@ struct etnaviv_iommuv2_domain {
>  	dma_addr_t stlb_dma[1024];
>  };
>  
> -static struct etnaviv_iommuv2_domain *to_etnaviv_domain(struct
> iommu_domain *domain)
> +static struct etnaviv_iommuv2_domain *
> +to_etnaviv_domain(struct etnaviv_iommu_domain *domain)
>  {
> -	return container_of(domain, struct etnaviv_iommuv2_domain,
> domain);
> +	return container_of(domain, struct etnaviv_iommuv2_domain,
> base);
>  }
>  
> -static int etnaviv_iommuv2_map(struct iommu_domain *domain, unsigned
> long iova,
> -	   phys_addr_t paddr, size_t size, int prot)
> +static int etnaviv_iommuv2_map(struct etnaviv_iommu_domain *domain,
> +			       unsigned long iova, phys_addr_t paddr,
> +			       size_t size, int prot)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain =
>  			to_etnaviv_domain(domain);
> @@ -68,7 +69,7 @@ static int etnaviv_iommuv2_map(struct iommu_domain
> *domain, unsigned long iova,
>  	if (size != SZ_4K)
>  		return -EINVAL;
>  
> -	if (prot & IOMMU_WRITE)
> +	if (prot & ETNAVIV_PROT_WRITE)
>  		entry |= MMUv2_PTE_WRITEABLE;
>  
>  	mtlb_entry = (iova & MMUv2_MTLB_MASK) >> MMUv2_MTLB_SHIFT;
> @@ -79,8 +80,8 @@ static int etnaviv_iommuv2_map(struct iommu_domain
> *domain, unsigned long iova,
>  	return 0;
>  }
>  
> -static size_t etnaviv_iommuv2_unmap(struct iommu_domain *domain,
> -	unsigned long iova, size_t size)
> +static size_t etnaviv_iommuv2_unmap(struct etnaviv_iommu_domain
> *domain,
> +				    unsigned long iova, size_t size)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain =
>  			to_etnaviv_domain(domain);
> @@ -166,7 +167,7 @@ static int etnaviv_iommuv2_init(struct
> etnaviv_iommuv2_domain *etnaviv_domain)
>  	return ret;
>  }
>  
> -static void etnaviv_iommuv2_domain_free(struct iommu_domain *domain)
> +static void etnaviv_iommuv2_domain_free(struct etnaviv_iommu_domain
> *domain)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain =
>  			to_etnaviv_domain(domain);
> @@ -190,7 +191,7 @@ static void etnaviv_iommuv2_domain_free(struct
> iommu_domain *domain)
>  	vfree(etnaviv_domain);
>  }
>  
> -static size_t etnaviv_iommuv2_dump_size(struct iommu_domain *domain)
> +static size_t etnaviv_iommuv2_dump_size(struct etnaviv_iommu_domain
> *domain)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain =
>  			to_etnaviv_domain(domain);
> @@ -204,7 +205,7 @@ static size_t etnaviv_iommuv2_dump_size(struct
> iommu_domain *domain)
>  	return dump_size;
>  }
>  
> -static void etnaviv_iommuv2_dump(struct iommu_domain *domain, void
> *buf)
> +static void etnaviv_iommuv2_dump(struct etnaviv_iommu_domain *domain,
> void *buf)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain =
>  			to_etnaviv_domain(domain);
> @@ -217,17 +218,6 @@ static void etnaviv_iommuv2_dump(struct
> iommu_domain *domain, void *buf)
>  			memcpy(buf, etnaviv_domain->stlb_cpu[i],
> SZ_4K);
>  }
>  
> -static const struct etnaviv_iommu_ops etnaviv_iommu_ops = {
> -	.ops = {
> -		.domain_free = etnaviv_iommuv2_domain_free,
> -		.map = etnaviv_iommuv2_map,
> -		.unmap = etnaviv_iommuv2_unmap,
> -		.pgsize_bitmap = SZ_4K,
> -	},
> -	.dump_size = etnaviv_iommuv2_dump_size,
> -	.dump = etnaviv_iommuv2_dump,
> -};
> -

Do we care about unconstification of these function pointers?

>  void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain =
> @@ -247,9 +237,11 @@ void etnaviv_iommuv2_restore(struct etnaviv_gpu
> *gpu)
>  
>  	gpu_write(gpu, VIVS_MMUv2_CONTROL,
> VIVS_MMUv2_CONTROL_ENABLE);
>  }
> -struct iommu_domain *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu
> *gpu)
> +struct etnaviv_iommu_domain *
> +etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu)
>  {
>  	struct etnaviv_iommuv2_domain *etnaviv_domain;
> +	struct etnaviv_iommu_domain *domain;
>  	int ret;
>  
>  	etnaviv_domain = vzalloc(sizeof(*etnaviv_domain));
> @@ -257,18 +249,21 @@ struct iommu_domain
> *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu)
>  		return NULL;
>  
>  	etnaviv_domain->dev = gpu->dev;
> +	domain = &etnaviv_domain->base;
>  
> -	etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING;
> -	etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops;
> -	etnaviv_domain->domain.pgsize_bitmap = SZ_4K;
> -	etnaviv_domain->domain.geometry.aperture_start = 0;
> -	etnaviv_domain->domain.geometry.aperture_end = ~0UL & ~(SZ_4K
> - 1);
> +	domain->free = etnaviv_iommuv2_domain_free;
> +	domain->map = etnaviv_iommuv2_map;
> +	domain->unmap = etnaviv_iommuv2_unmap,
> +	domain->dump_size = etnaviv_iommuv2_dump_size;
> +	domain->dump = etnaviv_iommuv2_dump;
> +	domain->base = 0;
> +	domain->size = (u64)SZ_1G * 4;
>  
>  	ret = etnaviv_iommuv2_init(etnaviv_domain);
>  	if (ret)
>  		goto out_free;
>  
> -	return &etnaviv_domain->domain;
> +	return &etnaviv_domain->base;
>  
>  out_free:
>  	vfree(etnaviv_domain);
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
> b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
> index 9f1f214e2918..7e52263623b8 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
> @@ -22,7 +22,8 @@
>  #include "etnaviv_iommu.h"
>  #include "etnaviv_mmu.h"
>  
> -size_t etnaviv_domain_unmap(struct iommu_domain *domain, unsigned
> long iova, size_t size)
> +size_t etnaviv_domain_unmap(struct etnaviv_iommu_domain *domain,
> +			    unsigned long iova, size_t size)
>  {
>  	size_t unmapped_page, unmapped = 0;
>  	size_t pgsize = SZ_4K;
> @@ -34,7 +35,7 @@ size_t etnaviv_domain_unmap(struct iommu_domain
> *domain, unsigned long iova, siz
>  	}
>  
>  	while (unmapped < size) {
> -		unmapped_page = domain->ops->unmap(domain, iova,
> pgsize);
> +		unmapped_page = domain->unmap(domain, iova, pgsize);
>  		if (!unmapped_page)
>  			break;
>  
> @@ -45,8 +46,9 @@ size_t etnaviv_domain_unmap(struct iommu_domain
> *domain, unsigned long iova, siz
>  	return unmapped;
>  }
>  
> -static int etnaviv_domain_map(struct iommu_domain *domain, unsigned
> long iova,
> -		     phys_addr_t paddr, size_t size, int prot)
> +static int etnaviv_domain_map(struct etnaviv_iommu_domain *domain,
> +			      unsigned long iova, phys_addr_t paddr,
> +			      size_t size, int prot)
>  {
>  	unsigned long orig_iova = iova;
>  	size_t pgsize = SZ_4K;
> @@ -60,7 +62,7 @@ static int etnaviv_domain_map(struct iommu_domain
> *domain, unsigned long iova,
>  	}
>  
>  	while (size) {
> -		ret = domain->ops->map(domain, iova, paddr, pgsize,
> prot);
> +		ret = domain->map(domain, iova, paddr, pgsize, prot);
>  		if (ret)
>  			break;
>  
> @@ -79,7 +81,7 @@ static int etnaviv_domain_map(struct iommu_domain
> *domain, unsigned long iova,
>  static int etnaviv_iommu_map(struct etnaviv_iommu *iommu, u32 iova,
>  			     struct sg_table *sgt, unsigned len, int
> prot)
>  {
> -	struct iommu_domain *domain = iommu->domain;
> +	struct etnaviv_iommu_domain *domain = iommu->domain;
>  	struct scatterlist *sg;
>  	unsigned int da = iova;
>  	unsigned int i, j;
> @@ -118,7 +120,7 @@ static int etnaviv_iommu_map(struct etnaviv_iommu
> *iommu, u32 iova,
>  static int etnaviv_iommu_unmap(struct etnaviv_iommu *iommu, u32 iova,
>  			       struct sg_table *sgt, unsigned len)

Should this be changed to a static void function? The return value of
etnaviv_iommu_unmap is never checked.

>  {
> -	struct iommu_domain *domain = iommu->domain;
> +	struct etnaviv_iommu_domain *domain = iommu->domain;
>  	struct scatterlist *sg;
>  	unsigned int da = iova;
>  	int i;
> @@ -284,7 +286,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu
> *mmu,
>  	mmu->last_iova = node->start + etnaviv_obj->base.size;
>  	mapping->iova = node->start;
>  	ret = etnaviv_iommu_map(mmu, node->start, sgt, etnaviv_obj-
> >base.size,
> -				IOMMU_READ | IOMMU_WRITE);
> +				ETNAVIV_PROT_READ |
> ETNAVIV_PROT_WRITE);
>  
>  	if (ret < 0) {
>  		drm_mm_remove_node(node);
> @@ -318,7 +320,7 @@ void etnaviv_iommu_unmap_gem(struct etnaviv_iommu
> *mmu,
>  void etnaviv_iommu_destroy(struct etnaviv_iommu *mmu)
>  {
>  	drm_mm_takedown(&mmu->mm);
> -	iommu_domain_free(mmu->domain);
> +	mmu->domain->free(mmu->domain);
>  	kfree(mmu);
>  }
>  
> @@ -350,9 +352,7 @@ struct etnaviv_iommu *etnaviv_iommu_new(struct
> etnaviv_gpu *gpu)
>  	mutex_init(&mmu->lock);
>  	INIT_LIST_HEAD(&mmu->mappings);
>  
> -	drm_mm_init(&mmu->mm, mmu->domain->geometry.aperture_start,
> -		    mmu->domain->geometry.aperture_end -
> -		    mmu->domain->geometry.aperture_start + 1);
> +	drm_mm_init(&mmu->mm, mmu->domain->base, mmu->domain->size);
>  
>  	return mmu;
>  }
> @@ -384,7 +384,7 @@ int etnaviv_iommu_get_suballoc_va(struct
> etnaviv_gpu *gpu, dma_addr_t paddr,
>  			return ret;
>  		}
>  		ret = etnaviv_domain_map(mmu->domain, vram_node-
> >start, paddr,
> -					 size, IOMMU_READ);
> +					 size, ETNAVIV_PROT_READ);
>  		if (ret < 0) {
>  			drm_mm_remove_node(vram_node);
>  			mutex_unlock(&mmu->lock);
> @@ -414,18 +414,10 @@ void etnaviv_iommu_put_suballoc_va(struct
> etnaviv_gpu *gpu,
>  }
>  size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu)
>  {
> -	struct etnaviv_iommu_ops *ops;
> -
> -	ops = container_of(iommu->domain->ops, struct
> etnaviv_iommu_ops, ops);
> -
> -	return ops->dump_size(iommu->domain);
> +	return iommu->domain->dump_size(iommu->domain);
>  }
>  
>  void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf)
>  {
> -	struct etnaviv_iommu_ops *ops;
> -
> -	ops = container_of(iommu->domain->ops, struct
> etnaviv_iommu_ops, ops);
> -
> -	ops->dump(iommu->domain, buf);
> +	iommu->domain->dump(iommu->domain, buf);
>  }
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
> b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
> index d072eda7a00d..38301b9d48e8 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
> @@ -17,7 +17,8 @@
>  #ifndef __ETNAVIV_MMU_H__
>  #define __ETNAVIV_MMU_H__
>  
> -#include <linux/iommu.h>
> +#define ETNAVIV_PROT_READ	(1 << 0)
> +#define ETNAVIV_PROT_WRITE	(1 << 1)
>  
>  enum etnaviv_iommu_version {
>  	ETNAVIV_IOMMU_V1 = 0,
> @@ -26,16 +27,23 @@ enum etnaviv_iommu_version {
>  
>  struct etnaviv_gpu;
>  struct etnaviv_vram_mapping;
> +struct etnaviv_iommu_domain;

This is superfluous, etnaviv_iommu_domain is defined right below:

> -struct etnaviv_iommu_ops {
> -	struct iommu_ops ops;
> -	size_t (*dump_size)(struct iommu_domain *);
> -	void (*dump)(struct iommu_domain *, void *);
> +struct etnaviv_iommu_domain {
> +	void (*free)(struct etnaviv_iommu_domain *);
> +	int (*map)(struct etnaviv_iommu_domain *domain, unsigned long
> iova,
> +		   phys_addr_t paddr, size_t size, int prot);
> +	size_t (*unmap)(struct etnaviv_iommu_domain *domain, unsigned
> long iova,
> +		     size_t size);
> +	size_t (*dump_size)(struct etnaviv_iommu_domain *);
> +	void (*dump)(struct etnaviv_iommu_domain *, void *);
> +	u64 base;
> +	u64 size;
>  };
>  
>  struct etnaviv_iommu {
>  	struct etnaviv_gpu *gpu;
> -	struct iommu_domain *domain;
> +	struct etnaviv_iommu_domain *domain;
>  
>  	enum etnaviv_iommu_version version;
>  

regards
Philipp


More information about the etnaviv mailing list