From patchwork Sat Sep 5 20:04:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 11759359 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8780615AB for ; Sat, 5 Sep 2020 20:06:29 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 490242073B for ; Sat, 5 Sep 2020 20:06:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="L2IRQ0Tf"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lTKPgGHM" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 490242073B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=TQyYfZ440L1+Dcu/tHjqHxiRZpRTWK3Us3CnAMGn50Q=; b=L2IRQ0Tf56r9bloATif3TCSNj JnsJWfXAukV9UctciAzfdVnE2XpB+nlV0idmg1/J688x+YFbtxuKMWUdBaalCI+JJ84dy0fQQLuG4 vTCP5aSURbHj0ZV6212ijChCUB0inOLC7SIlujuVFNjILxBI8APWffNDYnXU7/GDx0x03BKR4DdTJ ynxTObtKx7ZDayXeJPtRs2th1yh6XFtyY3tVGS9zbubUryt9XnR3P4aEfz+YmCi8WXw6MVas7HyJ8 5Z8qnyO5H7B5pGjp+0pYxDl7R4W8uIWutKxWNs3GG4LPRBinekIx3OQKHYBjiZFhFaJyzg0pXTgjJ Jb1fSKKYg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kEeQj-0007Ul-3V; Sat, 05 Sep 2020 20:04:57 +0000 Received: from mail-pj1-x1044.google.com ([2607:f8b0:4864:20::1044]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kEeQf-0007Sh-DP for linux-arm-kernel@lists.infradead.org; Sat, 05 Sep 2020 20:04:55 +0000 Received: by mail-pj1-x1044.google.com with SMTP id u3so1343254pjr.3 for ; Sat, 05 Sep 2020 13:04:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PAP++uQEfbrfeWkc7acc7DA5Qvr9EoHHyqUH0VD3He8=; b=lTKPgGHM4pGLFeVWDGXYCUbuie5QBl0D0r4wJvrzKdzx1t7F0ZQTjTPyR07Pg6h90J mRTG6eGN2piNIWVCYISt4OcEX42TuSU3XI72eM2ZW0qtjp0e/Ovrt3Wu47yMb2MekWn5 fd7VGwgOIBDpgxU/4Dv93xFAgj/l/HdzsoMVJk8M6vT3JQQa4RqfULHX/AWV/fpgwy2f 2QAtdCENab5Xdcvd7L2BwisTAJZcEwNvJOdjebp9oNrCatQQX1r5OOTZTvbf5g+T8h4O eFGViWWaLShbHH8fMlFM4VWYIXi2gCQV2i0TtzA484xVsYiSDSKTlf2/Lyv7rqEQkNxn pcCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PAP++uQEfbrfeWkc7acc7DA5Qvr9EoHHyqUH0VD3He8=; b=KpWLWWdkSbOuUGr4DOFZABkmgfiKQY3a+rZeg4SzqmNrkPRzvjJJvmBv3aVcaRXzW0 IrXfCyfRHciAoazM1pxg8NoNYPdEAAoPo18maMUBDNsFy68iQpwiTiqRynsiiJoiuxOI y5k+RTlETSTe1fGPAyJgH8UiHOwkXiz3651O5CoioFIDMRrwMZD01c+vdqHCWoHAGBQl ftOtxbRgxH0ASw4dxsUpnyToCukcpGmMB0amLodBG6sQrK969bQMbfKcGsrPdc9q0O6S 8h0cUOjJJUvcjJrZViYejToRsMiEE21CkfQtVt8UJW0YvOJnRs/uzQGuKvMu2uItshXV Jp7Q== X-Gm-Message-State: AOAM532Cf5AG9wxYk7q/b68q3TJVKRMpadiWmEqNgnpUhI8O551RGxfY 8J1g2bx4vAHTNGS0g7SuKwU= X-Google-Smtp-Source: ABdhPJycwwCLdWKq9ZKmLOfe22QCU1nLv2XzaQeZYPu3DeWjAfY2F1/8Q0WdLNAyBbKC6CG85iYkLA== X-Received: by 2002:a17:902:8a85:: with SMTP id p5mr13570330plo.193.1599336291107; Sat, 05 Sep 2020 13:04:51 -0700 (PDT) Received: from localhost (c-73-25-156-94.hsd1.or.comcast.net. [73.25.156.94]) by smtp.gmail.com with ESMTPSA id n67sm8287988pgn.14.2020.09.05.13.04.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 05 Sep 2020 13:04:50 -0700 (PDT) From: Rob Clark To: iommu@lists.linux-foundation.org, dri-devel@lists.freedesktop.org, Will Deacon , Robin Murphy , Joerg Roedel Subject: [PATCH v17 14/20] iommu/arm-smmu: Prepare for the adreno-smmu implementation Date: Sat, 5 Sep 2020 13:04:20 -0700 Message-Id: <20200905200454.240929-15-robdclark@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200905200454.240929-1-robdclark@gmail.com> References: <20200905200454.240929-1-robdclark@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200905_160454_019387_297C330D X-CRM114-Status: GOOD ( 24.48 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:1044 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [robdclark[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Clark , open list , Jonathan Marek , linux-arm-msm@vger.kernel.org, Hanna Hawa , Akhil P Oommen , Stephen Boyd , Jordan Crouse , Sibi Sankar , Vivek Gautam , Greg Kroah-Hartman , Bjorn Andersson , freedreno@lists.freedesktop.org, "moderated list:ARM SMMU DRIVERS" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Jordan Crouse Do a bit of prep work to add the upcoming adreno-smmu implementation. Add an hook to allow the implementation to choose which context banks to allocate. Move some of the common structs to arm-smmu.h in anticipation of them being used by the implementations and update some of the existing hooks to pass more information that the implementation will need. These modifications will be used by the upcoming Adreno SMMU implementation to identify the GPU device and properly configure it for pagetable switching. Co-developed-by: Rob Clark Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark Reviewed-by: Bjorn Andersson --- drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 2 +- drivers/iommu/arm/arm-smmu/arm-smmu.c | 74 ++++++---------------- drivers/iommu/arm/arm-smmu/arm-smmu.h | 52 ++++++++++++++- 3 files changed, 73 insertions(+), 55 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c index a9861dcd0884..88f17cc33023 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c @@ -69,7 +69,7 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu) } static int cavium_init_context(struct arm_smmu_domain *smmu_domain, - struct io_pgtable_cfg *pgtbl_cfg) + struct io_pgtable_cfg *pgtbl_cfg, struct device *dev) { struct cavium_smmu *cs = container_of(smmu_domain->smmu, struct cavium_smmu, smmu); diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 8e884e58f208..dad7fa86fbd4 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -65,41 +65,10 @@ module_param(disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, "Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU."); -struct arm_smmu_s2cr { - struct iommu_group *group; - int count; - enum arm_smmu_s2cr_type type; - enum arm_smmu_s2cr_privcfg privcfg; - u8 cbndx; -}; - #define s2cr_init_val (struct arm_smmu_s2cr){ \ .type = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS, \ } -struct arm_smmu_smr { - u16 mask; - u16 id; - bool valid; -}; - -struct arm_smmu_cb { - u64 ttbr[2]; - u32 tcr[2]; - u32 mair[2]; - struct arm_smmu_cfg *cfg; -}; - -struct arm_smmu_master_cfg { - struct arm_smmu_device *smmu; - s16 smendx[]; -}; -#define INVALID_SMENDX -1 -#define cfg_smendx(cfg, fw, i) \ - (i >= fw->num_ids ? INVALID_SMENDX : cfg->smendx[i]) -#define for_each_cfg_sme(cfg, fw, i, idx) \ - for (i = 0; idx = cfg_smendx(cfg, fw, i), i < fw->num_ids; ++i) - static bool using_legacy_binding, using_generic_binding; static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu) @@ -234,19 +203,6 @@ static int arm_smmu_register_legacy_master(struct device *dev, } #endif /* CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS */ -static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end) -{ - int idx; - - do { - idx = find_next_zero_bit(map, end, start); - if (idx == end) - return -ENOSPC; - } while (test_and_set_bit(idx, map)); - - return idx; -} - static void __arm_smmu_free_bitmap(unsigned long *map, int idx) { clear_bit(idx, map); @@ -578,7 +534,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, } } -static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx) +void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx) { u32 reg; bool stage1; @@ -664,8 +620,19 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx) arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg); } +static int arm_smmu_alloc_context_bank(struct arm_smmu_domain *smmu_domain, + struct arm_smmu_device *smmu, + struct device *dev, unsigned int start) +{ + if (smmu->impl && smmu->impl->alloc_context_bank) + return smmu->impl->alloc_context_bank(smmu_domain, smmu, dev, start); + + return __arm_smmu_alloc_bitmap(smmu->context_map, start, smmu->num_context_banks); +} + static int arm_smmu_init_domain_context(struct iommu_domain *domain, - struct arm_smmu_device *smmu) + struct arm_smmu_device *smmu, + struct device *dev) { int irq, start, ret = 0; unsigned long ias, oas; @@ -780,10 +747,13 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, ret = -EINVAL; goto out_unlock; } - ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, - smmu->num_context_banks); - if (ret < 0) + + ret = arm_smmu_alloc_context_bank(smmu_domain, smmu, dev, start); + if (ret < 0) { goto out_unlock; + } + + smmu_domain->smmu = smmu; cfg->cbndx = ret; if (smmu->version < ARM_SMMU_V2) { @@ -798,8 +768,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, else cfg->asid = cfg->cbndx; - smmu_domain->smmu = smmu; - pgtbl_cfg = (struct io_pgtable_cfg) { .pgsize_bitmap = smmu->pgsize_bitmap, .ias = ias, @@ -810,7 +778,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, }; if (smmu->impl && smmu->impl->init_context) { - ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg); + ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg, dev); if (ret) goto out_clear_smmu; } @@ -1194,7 +1162,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) return ret; /* Ensure that the domain is finalised */ - ret = arm_smmu_init_domain_context(domain, smmu); + ret = arm_smmu_init_domain_context(domain, smmu, dev); if (ret < 0) goto rpm_put; diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index f3e456893f28..9aaacc906597 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -256,6 +256,21 @@ enum arm_smmu_implementation { QCOM_SMMUV2, }; +struct arm_smmu_s2cr { + struct iommu_group *group; + int count; + enum arm_smmu_s2cr_type type; + enum arm_smmu_s2cr_privcfg privcfg; + u8 cbndx; +}; + +struct arm_smmu_smr { + u16 mask; + u16 id; + bool valid; + bool pinned; +}; + struct arm_smmu_device { struct device *dev; @@ -331,6 +346,13 @@ struct arm_smmu_cfg { }; #define ARM_SMMU_INVALID_IRPTNDX 0xff +struct arm_smmu_cb { + u64 ttbr[2]; + u32 tcr[2]; + u32 mair[2]; + struct arm_smmu_cfg *cfg; +}; + enum arm_smmu_domain_stage { ARM_SMMU_DOMAIN_S1 = 0, ARM_SMMU_DOMAIN_S2, @@ -350,6 +372,11 @@ struct arm_smmu_domain { struct iommu_domain domain; }; +struct arm_smmu_master_cfg { + struct arm_smmu_device *smmu; + s16 smendx[]; +}; + static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg) { u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) | @@ -400,14 +427,36 @@ struct arm_smmu_impl { int (*cfg_probe)(struct arm_smmu_device *smmu); int (*reset)(struct arm_smmu_device *smmu); int (*init_context)(struct arm_smmu_domain *smmu_domain, - struct io_pgtable_cfg *cfg); + struct io_pgtable_cfg *cfg, struct device *dev); void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync, int status); int (*def_domain_type)(struct device *dev); irqreturn_t (*global_fault)(int irq, void *dev); irqreturn_t (*context_fault)(int irq, void *dev); + int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain, + struct arm_smmu_device *smmu, + struct device *dev, int start); }; +#define INVALID_SMENDX -1 +#define cfg_smendx(cfg, fw, i) \ + (i >= fw->num_ids ? INVALID_SMENDX : cfg->smendx[i]) +#define for_each_cfg_sme(cfg, fw, i, idx) \ + for (i = 0; idx = cfg_smendx(cfg, fw, i), i < fw->num_ids; ++i) + +static inline int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end) +{ + int idx; + + do { + idx = find_next_zero_bit(map, end, start); + if (idx == end) + return -ENOSPC; + } while (test_and_set_bit(idx, map)); + + return idx; +} + static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n) { return smmu->base + (n << smmu->pgshift); @@ -472,6 +521,7 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu); struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu); struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu); +void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx); int arm_mmu500_reset(struct arm_smmu_device *smmu); #endif /* _ARM_SMMU_H */