From b52fb8dcc6922ac61b2edd7d6368ad10d7157688 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 30 Oct 2019 10:16:15 -0600 Subject: [PATCH] msm: kgsl: Refactor IOMMU contexts There are only two IOMMU contexts that we care about and there is no need to keep an array and all the associated detritus that comes with it. Change-Id: Ic0dedbad658c9e8ef58e676b0294fcc142b544c7 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno_iommu.c | 4 +- drivers/gpu/msm/kgsl_iommu.c | 71 ++++++++++++++++------------------ drivers/gpu/msm/kgsl_iommu.h | 13 ++----- 3 files changed, 40 insertions(+), 48 deletions(-) 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 ab44009a84be..1f76ad5c3070 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -553,13 +553,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; @@ -582,8 +590,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); @@ -598,6 +604,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); @@ -606,9 +614,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)) { @@ -814,7 +819,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; /* @@ -823,19 +827,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); } @@ -1006,7 +1008,7 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) struct kgsl_iommu_pt *iommu_pt = NULL; unsigned int cb_num; 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); @@ -1083,7 +1085,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; @@ -1134,7 +1136,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; @@ -1255,10 +1257,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; @@ -1290,12 +1291,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; @@ -1347,7 +1347,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; @@ -1409,7 +1409,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; @@ -1456,7 +1456,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; } @@ -1770,7 +1770,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) { @@ -1797,7 +1797,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) { /* @@ -1830,7 +1830,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 @@ -1861,7 +1861,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; @@ -1919,7 +1919,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); @@ -2304,9 +2304,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; @@ -2316,13 +2316,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); @@ -2396,7 +2393,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) { @@ -2407,7 +2404,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 5c0433fad221..73fdf8f8497f 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;