mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
Merge "msm: kgsl: Move the GMU kernel IOMMU device to the GMU platform device"
This commit is contained in:
commit
653a9c02c2
3 changed files with 25 additions and 133 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue