Merge "msm: kgsl: Move the GMU kernel IOMMU device to the GMU platform device"

This commit is contained in:
qctecmdr 2020-09-15 18:31:50 -07:00 • committed by Gerrit - the friendly Code Review server
commit 653a9c02c2
3 changed files with 25 additions and 133 deletions

View file

@ -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;

View file

@ -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

View file

@ -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",