diff --git a/drivers/gpu/msm/adreno_iommu.c b/drivers/gpu/msm/adreno_iommu.c index f92f6b65e17f..40954f07d5f9 100644 --- a/drivers/gpu/msm/adreno_iommu.c +++ b/drivers/gpu/msm/adreno_iommu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. */ #include @@ -235,7 +235,7 @@ unsigned int adreno_iommu_set_pt_generate_cmds( struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb); struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; u64 ttbr0; u32 contextidr; diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 7478276ff3c3..211b22e9ae31 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -558,13 +558,21 @@ static struct kgsl_process_private *kgsl_iommu_get_process(u64 ptbase) return NULL; } +static struct kgsl_iommu_context * +iommu_context_by_name(struct kgsl_iommu *iommu, u32 name) +{ + if (name == KGSL_MMU_SECURE_PT) + return &iommu->secure_context; + + return &iommu->user_context; +} + static int kgsl_iommu_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long addr, int flags, void *token) { int ret = 0; struct kgsl_pagetable *pt = token; struct kgsl_mmu *mmu = pt->mmu; - struct kgsl_iommu *iommu; struct kgsl_iommu_context *ctx; u64 ptbase; u32 contextidr; @@ -587,8 +595,6 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, if (mmu == NULL) return ret; - iommu = _IOMMU_PRIV(mmu); - ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; device = KGSL_MMU_DEVICE(mmu); adreno_dev = ADRENO_DEVICE(device); gpudev = ADRENO_GPU_DEVICE(adreno_dev); @@ -603,6 +609,8 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, else if (flags & IOMMU_FAULT_TRANSACTION_STALLED) fault_type = "transaction stalled"; + ctx = iommu_context_by_name(_IOMMU_PRIV(mmu), pt->name); + ptbase = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0); private = kgsl_iommu_get_process(ptbase); @@ -611,9 +619,6 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, comm = private->comm; } - if (pt->name == KGSL_MMU_SECURE_PT) - ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; - if (test_bit(KGSL_FT_PAGEFAULT_GPUHALT_ENABLE, &adreno_dev->ft_pf_policy) && (flags & IOMMU_FAULT_TRANSACTION_STALLED)) { @@ -819,7 +824,6 @@ static void kgsl_iommu_destroy_pagetable(struct kgsl_pagetable *pt) struct kgsl_iommu_pt *iommu_pt = pt->priv; struct kgsl_mmu *mmu = pt->mmu; struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); - struct kgsl_iommu *iommu; struct kgsl_iommu_context *ctx; /* @@ -828,19 +832,17 @@ static void kgsl_iommu_destroy_pagetable(struct kgsl_pagetable *pt) */ WARN_ON(!list_empty(&pt->list)); - iommu = _IOMMU_PRIV(mmu); + ctx = iommu_context_by_name(_IOMMU_PRIV(mmu), pt->name); if (pt->name == KGSL_MMU_SECURE_PT) { struct kgsl_global_memdesc *md; - ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; /* Unmap any pending secure global buffers */ list_for_each_entry(md, &device->globals, node) { if (md->memdesc.flags & KGSL_MEMFLAGS_SECURE) kgsl_mmu_unmap(pt, &md->memdesc); } } else { - ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; kgsl_iommu_unmap_globals(mmu, pt); } @@ -1015,7 +1017,7 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) unsigned int cb_num; unsigned int cb0_offset; struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); @@ -1100,7 +1102,7 @@ static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) int ret = 0; struct kgsl_iommu_pt *iommu_pt = NULL; struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; + struct kgsl_iommu_context *ctx = &iommu->secure_context; int secure_vmid = VMID_CP_PIXEL; struct kgsl_global_memdesc *md; @@ -1151,7 +1153,7 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) int ret = 0; struct kgsl_iommu_pt *iommu_pt = NULL; struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; int dynamic = 1; unsigned int cb_num = ctx->cb_num; @@ -1272,10 +1274,9 @@ static void _detach_context(struct kgsl_iommu_context *ctx) static void kgsl_iommu_close(struct kgsl_mmu *mmu) { struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - int i; - for (i = 0; i < KGSL_IOMMU_CONTEXT_MAX; i++) - _detach_context(&iommu->ctx[i]); + _detach_context(&iommu->user_context); + _detach_context(&iommu->secure_context); kgsl_mmu_putpagetable(mmu->defaultpagetable); mmu->defaultpagetable = NULL; @@ -1307,12 +1308,11 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu) { struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; int status = 0; mmu->features |= KGSL_MMU_PAGED; - if (ctx->name == NULL) { + if (!iommu->user_context.name) { dev_err(device->dev, "dt: gfx3d0_user context bank not found\n"); return -EINVAL; @@ -1364,7 +1364,7 @@ static int _setup_user_context(struct kgsl_mmu *mmu) { int ret = 0; struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_iommu_pt *iommu_pt = NULL; @@ -1426,7 +1426,7 @@ static int _setup_secure_context(struct kgsl_mmu *mmu) { int ret; struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; + struct kgsl_iommu_context *ctx = &iommu->secure_context; struct kgsl_iommu_pt *iommu_pt; @@ -1473,7 +1473,7 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu) status = _setup_secure_context(mmu); if (status) { - _detach_context(&iommu->ctx[KGSL_IOMMU_CONTEXT_USER]); + _detach_context(&iommu->user_context); return status; } @@ -1787,7 +1787,7 @@ static int kgsl_iommu_map_offset(struct kgsl_pagetable *pt, static void kgsl_iommu_clear_fsr(struct kgsl_mmu *mmu) { struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; unsigned int sctlr_val; if (ctx->default_pt != NULL && ctx->stalled_on_fault) { @@ -1814,7 +1814,7 @@ static void kgsl_iommu_clear_fsr(struct kgsl_mmu *mmu) static void kgsl_iommu_pagefault_resume(struct kgsl_mmu *mmu) { struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; if (ctx->default_pt != NULL && ctx->stalled_on_fault) { /* @@ -1847,7 +1847,7 @@ kgsl_iommu_get_current_ttbr0(struct kgsl_mmu *mmu) { u64 val; struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; /* * We cannot enable or disable the clocks in interrupt context, this @@ -1878,7 +1878,7 @@ kgsl_iommu_get_current_ttbr0(struct kgsl_mmu *mmu) static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) { struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; uint64_t ttbr0, temp; unsigned int contextidr; unsigned long wait_for_flush; @@ -1936,7 +1936,7 @@ static int kgsl_iommu_set_pf_policy(struct kgsl_mmu *mmu, unsigned long pf_policy) { struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); - struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; + struct kgsl_iommu_context *ctx = &iommu->user_context; struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); struct adreno_device *adreno_dev = ADRENO_DEVICE(device); @@ -2321,9 +2321,9 @@ static bool kgsl_iommu_addr_in_range(struct kgsl_pagetable *pagetable, } static int kgsl_iommu_probe_child(struct kgsl_device *device, - struct device_node *parent, int id, const char *name) + struct device_node *parent, struct kgsl_iommu_context *context, + const char *name) { - struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); struct device_node *node = of_find_node_by_name(parent, name); struct platform_device *pdev; struct device_node *phandle; @@ -2333,13 +2333,10 @@ static int kgsl_iommu_probe_child(struct kgsl_device *device, pdev = of_find_device_by_node(node); - iommu->ctx[id].id = id; - iommu->ctx[id].cb_num = -1; - iommu->ctx[id].name = name; - - iommu->ctx[id].kgsldev = device; - - iommu->ctx[id].pdev = pdev; + context->cb_num = -1; + context->name = name; + context->kgsldev = device; + context->pdev = pdev; phandle = of_parse_phandle(node, "iommus", 0); @@ -2413,7 +2410,7 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, of_platform_populate(node, NULL, NULL, &pdev->dev); /* The "user" device always needs to be present */ - ret = kgsl_iommu_probe_child(device, node, KGSL_IOMMU_CONTEXT_USER, + ret = kgsl_iommu_probe_child(device, node, &iommu->user_context, "gfx3d_user"); if (!ret && device->mmu.secured) { @@ -2424,7 +2421,7 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, /* Secure context bank devices are optional */ if (kgsl_iommu_probe_child(device, node, - KGSL_IOMMU_CONTEXT_SECURE, name)) + &iommu->secure_context, name)) device->mmu.secured = false; } diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h index 64a0a8c85098..645525a9eee0 100644 --- a/drivers/gpu/msm/kgsl_iommu.h +++ b/drivers/gpu/msm/kgsl_iommu.h @@ -68,12 +68,6 @@ enum kgsl_iommu_reg_map { /* Max number of iommu clks per IOMMU unit */ #define KGSL_IOMMU_MAX_CLKS 5 -enum kgsl_iommu_context_id { - KGSL_IOMMU_CONTEXT_USER = 0, - KGSL_IOMMU_CONTEXT_SECURE = 1, - KGSL_IOMMU_CONTEXT_MAX, -}; - /* offset at which a nop command is placed in setstate */ #define KGSL_IOMMU_SETSTATE_NOP_OFFSET 1024 @@ -94,7 +88,6 @@ enum kgsl_iommu_context_id { struct kgsl_iommu_context { struct platform_device *pdev; const char *name; - enum kgsl_iommu_context_id id; unsigned int cb_num; struct kgsl_device *kgsldev; bool stalled_on_fault; @@ -104,7 +97,6 @@ struct kgsl_iommu_context { /* * struct kgsl_iommu - Structure holding iommu data for kgsl driver - * @ctx: Array of kgsl_iommu_context structs * @regbase: Virtual address of the IOMMU register base * @regstart: Physical address of the iommu registers * @regsize: Length of the iommu register region. @@ -114,7 +106,10 @@ struct kgsl_iommu_context { * @smmu_info: smmu info used in a5xx preemption */ struct kgsl_iommu { - struct kgsl_iommu_context ctx[KGSL_IOMMU_CONTEXT_MAX]; + /** @user_context: Container for the user iommu context */ + struct kgsl_iommu_context user_context; + /** @secure_context: Container for the secure iommu context */ + struct kgsl_iommu_context secure_context; void __iomem *regbase; unsigned long regstart; unsigned int regsize;