diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 21a34d2e8e54..4be6ff6b4c55 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -24,12 +24,6 @@ #include "kgsl_trace.h" #include "kgsl_util.h" -struct gmu_iommu_context { - const char *name; - struct platform_device *pdev; - struct iommu_domain *domain; -}; - #define ARC_VOTE_GET_PRI(_v) ((_v) & 0xFF) #define ARC_VOTE_GET_SEC(_v) (((_v) >> 8) & 0xFF) #define ARC_VOTE_GET_VLVL(_v) (((_v) >> 16) & 0xFFFF) @@ -61,11 +55,6 @@ static struct gmu_vma_entry a6xx_gmu_vma_legacy[] = { .size = SZ_512M, .next_va = 0x60000000 }, - [GMU_NONCACHED_USER] = { - .start = 0x80000000, - .size = SZ_1G, - .next_va = 0x80000000 - }, }; static struct gmu_vma_entry a6xx_gmu_vma[] = { @@ -91,16 +80,6 @@ static struct gmu_vma_entry a6xx_gmu_vma[] = { .size = SZ_512M, .next_va = 0x60000000 }, - [GMU_NONCACHED_USER] = { - .start = 0x80000000, - .size = SZ_1G, - .next_va = 0x80000000 - }, -}; - -static struct gmu_iommu_context a6xx_gmu_ctx[] = { - [GMU_CONTEXT_USER] = { .name = "gmu_user" }, - [GMU_CONTEXT_KERNEL] = { .name = "gmu_kernel" } }; static int timed_poll_check_rscc(struct kgsl_device *device, @@ -619,17 +598,6 @@ static int find_vma_block(struct a6xx_gmu_device *gmu, u32 addr, u32 size) return -ENOENT; } -struct iommu_domain *a6xx_get_gmu_domain(struct a6xx_gmu_device *gmu, - u32 gmuaddr, u32 size) -{ - u32 vma_id = find_vma_block(gmu, gmuaddr, size); - - if (vma_id == GMU_NONCACHED_USER) - return a6xx_gmu_ctx[GMU_CONTEXT_USER].domain; - - return a6xx_gmu_ctx[GMU_CONTEXT_KERNEL].domain; -} - static int _load_legacy_gmu_fw(struct kgsl_device *device, struct a6xx_gmu_device *gmu) { @@ -1436,7 +1404,7 @@ struct gmu_memdesc *reserve_gmu_kernel_block(struct a6xx_gmu_device *gmu, md->gmuaddr = addr; - ret = iommu_map(a6xx_get_gmu_domain(gmu, md->gmuaddr, md->size), addr, + ret = iommu_map(gmu->domain, addr, md->physaddr, md->size, IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV); if (ret) { dev_err(&gmu->pdev->dev, @@ -2435,18 +2403,6 @@ static int a6xx_gmu_bus_set(struct adreno_device *adreno_dev, int buslevel, return ret; } -static void a6xx_gmu_iommu_cb_close(struct gmu_iommu_context *ctx) -{ - if (!ctx->domain) - return; - - iommu_detach_device(ctx->domain, &ctx->pdev->dev); - iommu_domain_free(ctx->domain); - - platform_device_put(ctx->pdev); - ctx->domain = NULL; -} - static void a6xx_free_gmu_globals(struct a6xx_gmu_device *gmu) { int i; @@ -2457,7 +2413,7 @@ static void a6xx_free_gmu_globals(struct a6xx_gmu_device *gmu) if (!md->gmuaddr) continue; - iommu_unmap(a6xx_get_gmu_domain(gmu, md->gmuaddr, md->size), + iommu_unmap(gmu->domain, md->gmuaddr, md->size); dma_free_attrs(&gmu->pdev->dev, (size_t) md->size, @@ -2466,8 +2422,11 @@ static void a6xx_free_gmu_globals(struct a6xx_gmu_device *gmu) memset(md, 0, sizeof(*md)); } - a6xx_gmu_iommu_cb_close(&a6xx_gmu_ctx[GMU_CONTEXT_KERNEL]); - a6xx_gmu_iommu_cb_close(&a6xx_gmu_ctx[GMU_CONTEXT_USER]); + if (gmu->domain) { + iommu_detach_device(gmu->domain, &gmu->pdev->dev); + iommu_domain_free(gmu->domain); + gmu->domain = NULL; + } gmu->global_entries = 0; } @@ -2603,8 +2562,7 @@ void a6xx_gmu_remove(struct kgsl_device *device) } static int a6xx_gmu_iommu_fault_handler(struct iommu_domain *domain, - struct device *dev, unsigned long addr, int flags, void *token, - const char *name) + struct device *dev, unsigned long addr, int flags, void *token) { char *fault_type = "unknown"; @@ -2617,55 +2575,22 @@ static int a6xx_gmu_iommu_fault_handler(struct iommu_domain *domain, else if (flags & IOMMU_FAULT_TRANSACTION_STALLED) fault_type = "transaction stalled"; - dev_err(dev, "GMU fault addr = %lX, context=%s (%s %s fault)\n", - addr, name, + dev_err(dev, "GMU fault addr = %lX, context=kernel (%s %s fault)\n", + addr, (flags & IOMMU_FAULT_WRITE) ? "write" : "read", fault_type); return 0; } -static int a6xx_gmu_kernel_fault_handler(struct iommu_domain *domain, - struct device *dev, unsigned long addr, int flags, void *token) +static int a6xx_gmu_iommu_init(struct a6xx_gmu_device *gmu) { - return a6xx_gmu_iommu_fault_handler(domain, dev, addr, flags, token, - "gmu_kernel"); -} - -static int a6xx_gmu_user_fault_handler(struct iommu_domain *domain, - struct device *dev, unsigned long addr, int flags, void *token) -{ - return a6xx_gmu_iommu_fault_handler(domain, dev, addr, flags, token, - "gmu_user"); -} - -static int a6xx_gmu_iommu_cb_probe(struct a6xx_gmu_device *gmu, - struct gmu_iommu_context *ctx, struct device_node *parent, - iommu_fault_handler_t handler) -{ - struct device_node *node = of_get_child_by_name(parent, ctx->name); - struct platform_device *pdev; int ret; int no_stall = 1; - if (!node) - return -ENODEV; - - pdev = of_find_device_by_node(node); - ret = of_dma_configure(&pdev->dev, node, true); - of_node_put(node); - - if (ret) { - platform_device_put(pdev); - return ret; - } - - ctx->pdev = pdev; - ctx->domain = iommu_domain_alloc(&platform_bus_type); - if (ctx->domain == NULL) { - dev_err(&gmu->pdev->dev, "gmu iommu fail to alloc %s domain\n", - ctx->name); - platform_device_put(pdev); + gmu->domain = iommu_domain_alloc(&platform_bus_type); + if (gmu->domain == NULL) { + dev_err(&gmu->pdev->dev, "Unable to allocate GMU IOMMU domain\n"); return -ENODEV; } @@ -2674,40 +2599,24 @@ static int a6xx_gmu_iommu_cb_probe(struct a6xx_gmu_device *gmu, * This sets SCTLR.CFCFG = 0. * Also note that, the smmu driver sets SCTLR.HUPCF = 0 by default. */ - iommu_domain_set_attr(ctx->domain, + iommu_domain_set_attr(gmu->domain, DOMAIN_ATTR_FAULT_MODEL_NO_STALL, &no_stall); - ret = iommu_attach_device(ctx->domain, &pdev->dev); + ret = iommu_attach_device(gmu->domain, &gmu->pdev->dev); if (!ret) { - iommu_set_fault_handler(ctx->domain, handler, ctx); + iommu_set_fault_handler(gmu->domain, + a6xx_gmu_iommu_fault_handler, gmu); return 0; } dev_err(&gmu->pdev->dev, - "gmu iommu fail to attach %s device\n", ctx->name); - iommu_domain_free(ctx->domain); - ctx->domain = NULL; - platform_device_put(pdev); + "Unable to attach GMU IOMMU domain: %d\n", ret); + iommu_domain_free(gmu->domain); + gmu->domain = NULL; return ret; } -static int a6xx_gmu_iommu_init(struct a6xx_gmu_device *gmu, - struct device_node *node) -{ - int ret; - - devm_of_platform_populate(&gmu->pdev->dev); - - ret = a6xx_gmu_iommu_cb_probe(gmu, &a6xx_gmu_ctx[GMU_CONTEXT_USER], - node, a6xx_gmu_user_fault_handler); - if (ret) - return ret; - - return a6xx_gmu_iommu_cb_probe(gmu, &a6xx_gmu_ctx[GMU_CONTEXT_KERNEL], - node, a6xx_gmu_kernel_fault_handler); -} - int a6xx_gmu_probe(struct kgsl_device *device, struct platform_device *pdev) { @@ -2745,7 +2654,7 @@ int a6xx_gmu_probe(struct kgsl_device *device, gmu->num_clks = ret; /* Set up GMU IOMMU and shared memory with GMU */ - ret = a6xx_gmu_iommu_init(gmu, pdev->dev.of_node); + ret = a6xx_gmu_iommu_init(gmu); if (ret) goto error; diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.h b/drivers/gpu/msm/adreno_a6xx_gmu.h index 4c58f20d798e..ca301e31aa10 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.h +++ b/drivers/gpu/msm/adreno_a6xx_gmu.h @@ -91,11 +91,6 @@ enum gmu_mem_type { GMU_MEM_TYPE_MAX, }; -enum gmu_context_index { - GMU_CONTEXT_USER, - GMU_CONTEXT_KERNEL, -}; - /** * struct gmu_memdesc - Gmu shared memory object descriptor * @hostptr: Kernel virtual address @@ -204,6 +199,8 @@ struct a6xx_gmu_device { unsigned long flags; /** @rscc_virt: Pointer where RSCC block is mapped */ void __iomem *rscc_virt; + /** @domain: IOMMU domain for the kernel context */ + struct iommu_domain *domain; }; /* Helper function to get to a6xx gmu device from adreno device */ @@ -517,17 +514,4 @@ int a6xx_gmu_enable_clks(struct adreno_device *adreno_dev); */ int a6xx_gmu_enable_gdsc(struct adreno_device *adreno_dev); -/** - * a6xx_get_gmu_domain - Get the gmu iommu domain for a gmu memory block - * @gmu: Pointer to the a6xx gmu device - * @gmuaddr: Address of the memory block - * @size: Size in bytes of the memory block - * - * Based on the gmu address and size of a gmu memory block, get the gmu iommu - * domain to map the memory block to. - * - * Return: gmu iommu domain to which the given memory block is to be mapped - */ -struct iommu_domain *a6xx_get_gmu_domain(struct a6xx_gmu_device *gmu, - u32 gmuaddr, u32 size); #endif diff --git a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c index 1fd3dc29a921..2b965e5bb584 100644 --- a/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c +++ b/drivers/gpu/msm/adreno_a6xx_hwsched_hfi.c @@ -431,8 +431,7 @@ static int gmu_import_buffer(struct adreno_device *adreno_dev, desc->gmu_addr = vma->next_va; - mapped = iommu_map_sg(a6xx_get_gmu_domain(gmu, desc->gmu_addr, - desc->size), + mapped = iommu_map_sg(gmu->domain, desc->gmu_addr, sgt->sgl, sgt->nents, attrs); if (mapped == 0) dev_err(&gmu->pdev->dev, "gmu map sg err: 0x%08x, %d, %x, %zd\n",