From patchwork Tue Aug 14 10:55:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Gautam X-Patchwork-Id: 10565361 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4DEC91805 for ; Tue, 14 Aug 2018 11:12:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3918029923 for ; Tue, 14 Aug 2018 11:12:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2B42C29929; Tue, 14 Aug 2018 11:12:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8911C29923 for ; Tue, 14 Aug 2018 11:12:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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=S+jTe/7nsLPVJTwUMZNtMo8GwXwe2sQVWUCS/79jObA=; b=dth4GWhu3l78ZL /sMkZlIcZWvTTAx2HOWBIH2g+KhDZLLBGalu923LWbeGfGtzYemwx8vrp5zv6LpxH2h4e7TAynufm i0XwpztWZEIVPjemS8y+H4FpFmfjwET1ICzfoq2S06zrUFYXZDUStv1+cEsizuhRy7Wf4bssxb6hC jaC3z9t/5LwUtgwmim8VGx1Iqp5MtCT5mkq4jpUf/zEWLGY6mvgFzC3VljI2kP0+FOaJEenYZRTi5 UR57pvKF+9revmv1L5i4stkNiafOwVLT1gDwreYZgBFzsX9ran8tDHzVK9MJB0ZDwj1miGSwdMAfx 8+B3xyTWUL8Q6RDiaPyA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fpXFC-0004h1-6Y; Tue, 14 Aug 2018 11:12:10 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fpXF1-0004V3-RC for linux-arm-kernel@bombadil.infradead.org; Tue, 14 Aug 2018 11:11:59 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=0mcvVZ1eaDy+8Q6tkbI3xKuQ/qo8a2wB+JoPJCBqXas=; b=lpG6VeAfog7n2qvvFhHWL4Uac2 Mcn2JIAMVySjkre42Fme+kvrRveRhKep0M3ne2x2cfQMeKBnGQoi4a3fx6KGRiM9l1uO9ISFavnr/ 28HB6p9e4wp+Lm1hc3pwviIc/Xomg9fuSMc6xQnCY3/rF70LJVyRQalsybM6Lhu0T7lGoA9vxttLm of/I+BWp4L9XYXhyQaQEtvHG5vJaE9/gpjb56hr4JmogtJXbceWnF1ifrEuFuaOFFM5SGZxcyA8im +jATWJmSHxApMXztNdDfYv6EKE9X7DXk0Hk/255i6j4zGNJgv1D1juo26NNNF49Zmy2LmHERxPakq +zF+Cu2w==; Received: from smtp.codeaurora.org ([198.145.29.96]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fpX09-0005R8-75 for linux-arm-kernel@lists.infradead.org; Tue, 14 Aug 2018 10:56:39 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 94DB760D8B; Tue, 14 Aug 2018 10:56:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1534244185; bh=T2Tip3toqJ3MdEjOp9pX48cLklCZApH5GunCjlOEO3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M7qFBxwZdwBaUuFX/Il3A+nsLW6meS6MPf2mSKlYTypoQtYnj0ejIt+7EuaBVEpuq HQ+PDWi+gBZC5ezBkpxwqecwQwUqxJeHE7srOJ/j04r6VvcGSRL6Pxex4lcA9Qbaoh NR3FBRr2ese4qLxze9aVdthM+FsbWrCjZllJFVSA= Received: from blr-ubuntu-41.ap.qualcomm.com (blr-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.18.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vivek.gautam@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 9B9AC60CED; Tue, 14 Aug 2018 10:56:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1534244164; bh=T2Tip3toqJ3MdEjOp9pX48cLklCZApH5GunCjlOEO3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OSw6w/fpyTJ/A2d3NUpaRs1KkFzAw/p4RnZpetGQhtROQpeGDhEZ+9z8jdR6mujvN qvGxegEEMSYdlJqi2X7T6zT4CprBJyVC4HRRb6jTw7Gm8NmO6CcVwEZZmHwbuXOQFD 6HY1y7EM5SLOVnmaKNAGhI9dADbso1jdAWUZ4GtA= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 9B9AC60CED Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=vivek.gautam@codeaurora.org From: Vivek Gautam To: joro@8bytes.org, andy.gross@linaro.org, will.deacon@arm.com, robin.murphy@arm.com, bjorn.andersson@linaro.org, iommu@lists.linux-foundation.org Subject: [PATCH 5/5] iommu/arm-smmu: Add support to handle Qcom's TLBI serialization errata Date: Tue, 14 Aug 2018 16:25:28 +0530 Message-Id: <20180814105528.20592-6-vivek.gautam@codeaurora.org> X-Mailer: git-send-email 2.16.1.72.g5be1f00a9a70 In-Reply-To: <20180814105528.20592-1-vivek.gautam@codeaurora.org> References: <20180814105528.20592-1-vivek.gautam@codeaurora.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180814_115637_523033_F3CD4170 X-CRM114-Status: GOOD ( 21.50 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, swboyd@chromium.org, david.brown@linaro.org, Vivek Gautam , tfiga@chromium.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Qcom's implementation of arm,mmu-500 require to serialize all TLB invalidations for context banks. In case the TLB invalidation requests don't go through the first time, there's a way to disable/enable the wait for safe logic. Disabling this logic expadites the TLBIs. Different bootloaders with their access control policies allow this register access differntly. With one, we should be able to directly make qcom-scm call to do io read/write, while with other we should use the specific SCM command to send request to do the complete register configuration. A separate device tree flag for arm-smmu will allow to identify which firmware configuration of the two mentioned above we use. Signed-off-by: Vivek Gautam --- drivers/iommu/arm-smmu-regs.h | 2 + drivers/iommu/arm-smmu.c | 136 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h index a1226e4ab5f8..71662cae9806 100644 --- a/drivers/iommu/arm-smmu-regs.h +++ b/drivers/iommu/arm-smmu-regs.h @@ -177,6 +177,8 @@ enum arm_smmu_s2cr_privcfg { #define ARM_SMMU_CB_ATS1PR 0x800 #define ARM_SMMU_CB_ATSR 0x8f0 +#define ARM_SMMU_GID_QCOM_CUSTOM_CFG 0x300 + #define SCTLR_S1_ASIDPNE (1 << 12) #define SCTLR_CFCFG (1 << 7) #define SCTLR_CFIE (1 << 6) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 75c146751c87..fafdaeb4d097 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -179,7 +180,8 @@ struct arm_smmu_device { #define ARM_SMMU_FEAT_EXIDS (1 << 12) u32 features; -#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) +#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) +#define ARM_SMMU_OPT_QCOM_FW_IMPL_ERRATA (1 << 1) u32 options; enum arm_smmu_arch_version version; enum arm_smmu_implementation model; @@ -262,6 +264,7 @@ static bool using_legacy_binding, using_generic_binding; static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" }, + { ARM_SMMU_OPT_QCOM_FW_IMPL_ERRATA, "qcom,smmu-500-fw-impl-errata" }, { 0, NULL}, }; @@ -531,12 +534,137 @@ static void arm_smmu_tlb_inv_vmid_nosync(unsigned long iova, size_t size, writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID); } +#define CUSTOM_CFG_MDP_SAFE_ENABLE BIT(15) +#define CUSTOM_CFG_IFE1_SAFE_ENABLE BIT(14) +#define CUSTOM_CFG_IFE0_SAFE_ENABLE BIT(13) + +static int __qsmmu500_wait_safe_toggle(struct arm_smmu_device *smmu, int en) +{ + int ret; + u32 val, gid_phys_base; + phys_addr_t reg; + struct vm_struct *vm; + + /* We want physical address of SMMU, so the vm_area */ + vm = find_vm_area(smmu->base); + + /* + * GID (implementation defined address space) is located at + * SMMU_BASE + (2 × PAGESIZE). + */ + gid_phys_base = vm->phys_addr + (2 << (smmu)->pgshift); + reg = gid_phys_base + ARM_SMMU_GID_QCOM_CUSTOM_CFG; + + ret = qcom_scm_io_readl_atomic(reg, &val); + if (ret) + return ret; + + if (en) + val |= CUSTOM_CFG_MDP_SAFE_ENABLE | + CUSTOM_CFG_IFE0_SAFE_ENABLE | + CUSTOM_CFG_IFE1_SAFE_ENABLE; + else + val &= ~(CUSTOM_CFG_MDP_SAFE_ENABLE | + CUSTOM_CFG_IFE0_SAFE_ENABLE | + CUSTOM_CFG_IFE1_SAFE_ENABLE); + + ret = qcom_scm_io_writel_atomic(reg, val); + + return ret; +} + +static int qsmmu500_wait_safe_toggle(struct arm_smmu_device *smmu, + int en, bool is_fw_impl) +{ + if (is_fw_impl) + return qcom_scm_qsmmu500_wait_safe_toggle(en); + else + return __qsmmu500_wait_safe_toggle(smmu, en); +} + +static void qcom_errata_tlb_sync(struct arm_smmu_domain *smmu_domain) +{ + struct arm_smmu_device *smmu = smmu_domain->smmu; + void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx); + void __iomem *status = base + ARM_SMMU_CB_TLBSTATUS; + bool is_fw_impl; + + writel_relaxed(0, base + ARM_SMMU_CB_TLBSYNC); + + if (!__arm_smmu_tlb_sync_wait(status)) + return; + + is_fw_impl = smmu->options & ARM_SMMU_OPT_QCOM_FW_IMPL_ERRATA ? + true : false; + + /* SCM call here to disable the wait-for-safe logic. */ + if (WARN(qsmmu500_wait_safe_toggle(smmu, false, is_fw_impl), + "Failed to disable wait-safe logic, bad hw state\n")) + return; + + if (!__arm_smmu_tlb_sync_wait(status)) + return; + + /* SCM call here to re-enable the wait-for-safe logic. */ + WARN(qsmmu500_wait_safe_toggle(smmu, true, is_fw_impl), + "Failed to re-enable wait-safe logic, bad hw state\n"); + + dev_err_ratelimited(smmu->dev, + "TLB sync timed out -- SMMU in bad state\n"); +} + +static void __qcom_errata_tlb_sync_context(struct arm_smmu_domain *smmu_domain) +{ + qcom_errata_tlb_sync(smmu_domain); +} + +static void qcom_errata_tlb_sync_context(void *cookie) +{ + struct arm_smmu_domain *smmu_domain = cookie; + unsigned long flags; + + spin_lock_irqsave(&smmu_domain->cb_lock, flags); + qcom_errata_tlb_sync(smmu_domain); + spin_unlock_irqrestore(&smmu_domain->cb_lock, flags); +} + +static void qcom_errata_tlb_inv_context_s1(void *cookie) +{ + struct arm_smmu_domain *smmu_domain = cookie; + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + void __iomem *base = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx); + unsigned long flags; + + spin_lock_irqsave(&smmu_domain->cb_lock, flags); + writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID); + __qcom_errata_tlb_sync_context(cookie); + spin_unlock_irqrestore(&smmu_domain->cb_lock, flags); +} + +static void qcom_errata_tlb_inv_range_nosync(unsigned long iova, size_t size, + size_t granule, bool leaf, + void *cookie) +{ + struct arm_smmu_domain *smmu_domain = cookie; + unsigned long flags; + + spin_lock_irqsave(&smmu_domain->cb_lock, flags); + __arm_smmu_tlb_inv_range_nosync(iova, size, granule, leaf, cookie); + spin_unlock_irqrestore(&smmu_domain->cb_lock, flags); +} + static const struct iommu_gather_ops arm_smmu_s1_tlb_ops = { .tlb_flush_all = arm_smmu_tlb_inv_context_s1, .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, .tlb_sync = arm_smmu_tlb_sync_context, }; +static const struct iommu_gather_ops qcom_errata_s1_tlb_ops = { + .tlb_flush_all = qcom_errata_tlb_inv_context_s1, + .tlb_add_flush = qcom_errata_tlb_inv_range_nosync, + .tlb_sync = qcom_errata_tlb_sync_context, +}; + static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v2 = { .tlb_flush_all = arm_smmu_tlb_inv_context_s2, .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, @@ -824,7 +952,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, ias = min(ias, 32UL); oas = min(oas, 32UL); } - smmu_domain->tlb_ops = &arm_smmu_s1_tlb_ops; + if (of_device_is_compatible(smmu->dev->of_node, + "qcom,sdm845-smmu-500")) + smmu_domain->tlb_ops = &qcom_errata_s1_tlb_ops; + else + smmu_domain->tlb_ops = &arm_smmu_s1_tlb_ops; break; case ARM_SMMU_DOMAIN_NESTED: /*