Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp3148106ybi; Mon, 10 Jun 2019 05:22:09 -0700 (PDT) X-Google-Smtp-Source: APXvYqyXYhFuKQKPyBrkSFk6UnJ0NN4UC63EwNIbW9iFM0rGKd2X0ea8kYKYTOIpVhuOgWPBNzrK X-Received: by 2002:a17:902:b691:: with SMTP id c17mr47715812pls.107.1560169329910; Mon, 10 Jun 2019 05:22:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560169329; cv=none; d=google.com; s=arc-20160816; b=h8DwlUZl4NDDgD7X1+aBi9u/RogqQX+GqCqepN+tx5+MpEeIuINU/seTyoHYIdxWW+ bDMpEtZzD6hVcV/ARQr6LYFb/bQQ+tGCgiyIjE7gmCTyGr+TLkRIIIt2VymuxdYrtb2o xqqpnVzokYVfDo38txsGCEfAUKlZeKiPk0iCAfx1/t05vbji2KXWVVPAQSaqAbZWXzQB 0IGbJRDKjpctIoMhGoEWj7CttMXgdLsMQbvvkJoywbYvdMss9VXcGeZZnYx2X2UWTBJ/ ZQ8DjlYSBHDTZU+SLJmKZSYu31e0jNZE/obPochlUt0P1eukuYfFi3k31elovwYLCIX1 G9Jw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=aQIhdb79K4QKV6PJRa2R7JnrHnJVz/PirhYQ0DYR/lg=; b=EJrsjhzNurnZv8/5eyUcg/WC5BNo9pMX/xR0TqhDj1fYWJ90g60RcENP0Ulpvhn1Ty RcTnrm+LxJxv8zsBL4m/YivuGk2GVf8O2aL9oA7KQXcxKL38nDRJ86dWU7OoUq64ikZn gpK9THZzaYZoq5QRJnwxSNtyTHoUPjLmcewp0/ZetMCimSd4qlu3l6gtMdAHOf/hrR9r PKCsC1Bd8BLZ5TfZF43EUZtBxKCHy9b0L5OeSqQlbS0paj0cPWip9p9hFb+VRI6jgwAp SldnaykVNURjGNlccxC8VsEXMZBA6AR6eADRcZp+eJ48wDDTle0CHaChNcayO0aHWXLA lUEQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k13si9108432pll.64.2019.06.10.05.21.55; Mon, 10 Jun 2019 05:22:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389899AbfFJMTt (ORCPT + 99 others); Mon, 10 Jun 2019 08:19:49 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:22353 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S2389682AbfFJMTs (ORCPT ); Mon, 10 Jun 2019 08:19:48 -0400 X-UUID: 7192fe0e9eb64b79bbc2648a1893aaf5-20190610 X-UUID: 7192fe0e9eb64b79bbc2648a1893aaf5-20190610 Received: from mtkcas08.mediatek.inc [(172.21.101.126)] by mailgw02.mediatek.com (envelope-from ) (mhqrelay.mediatek.com ESMTP with TLS) with ESMTP id 1556585299; Mon, 10 Jun 2019 20:19:42 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 10 Jun 2019 20:19:42 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Mon, 10 Jun 2019 20:19:40 +0800 From: Yong Wu To: Joerg Roedel , Matthias Brugger , Robin Murphy , Rob Herring CC: Evan Green , Tomasz Figa , Will Deacon , , , , , , , , , , Nicolas Boichat , , Matthias Kaehlcke Subject: [PATCH v7 06/21] iommu/io-pgtable-arm-v7s: Extend MediaTek 4GB Mode Date: Mon, 10 Jun 2019 20:17:45 +0800 Message-ID: <1560169080-27134-7-git-send-email-yong.wu@mediatek.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1560169080-27134-1-git-send-email-yong.wu@mediatek.com> References: <1560169080-27134-1-git-send-email-yong.wu@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org MediaTek extend the arm v7s descriptor to support the dram over 4GB. In the mt2712 and mt8173, it's called "4GB mode", the physical address is from 0x4000_0000 to 0x1_3fff_ffff, but from EMI point of view, it is remapped to high address from 0x1_0000_0000 to 0x1_ffff_ffff, the bit32 is always enabled. thus, in the M4U, we always enable the bit9 for all PTEs which means to enable bit32 of physical address. but in mt8183, M4U support the dram from 0x4000_0000 to 0x3_ffff_ffff which isn't remaped. We extend the PTEs: the bit9 represent bit32 of PA and the bit4 represent bit33 of PA. Meanwhile the iova still is 32bits. In order to unify code, in the "4GB mode", we add the bit32 for the physical address manually in our driver. Correspondingly, Adding bit32 and bit33 for the PA in the iova_to_phys has to been moved into v7s. Regarding whether the pagetable address could be over 4GB, the mt8183 support it while the previous mt8173 don't. thus keep it as is. Signed-off-by: Yong Wu Reviewed-by: Robin Murphy Reviewed-by: Evan Green --- drivers/iommu/io-pgtable-arm-v7s.c | 31 ++++++++++++++++++++++++------- drivers/iommu/mtk_iommu.c | 20 ++++++++++---------- drivers/iommu/mtk_iommu.h | 1 + 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index 94c38db..4077822 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -123,7 +123,9 @@ #define ARM_V7S_TEX_MASK 0x7 #define ARM_V7S_ATTR_TEX(val) (((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT) -#define ARM_V7S_ATTR_MTK_4GB BIT(9) /* MTK extend it for 4GB mode */ +/* MediaTek extend the two bits below for over 4GB mode */ +#define ARM_V7S_ATTR_MTK_PA_BIT32 BIT(9) +#define ARM_V7S_ATTR_MTK_PA_BIT33 BIT(4) /* *well, except for TEX on level 2 large pages, of course :( */ #define ARM_V7S_CONT_PAGE_TEX_SHIFT 6 @@ -190,13 +192,22 @@ static dma_addr_t __arm_v7s_dma_addr(void *pages) static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl, struct io_pgtable_cfg *cfg) { - return paddr & ARM_V7S_LVL_MASK(lvl); + arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl); + + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB) { + if (paddr & BIT_ULL(32)) + pte |= ARM_V7S_ATTR_MTK_PA_BIT32; + if (paddr & BIT_ULL(33)) + pte |= ARM_V7S_ATTR_MTK_PA_BIT33; + } + return pte; } static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl, struct io_pgtable_cfg *cfg) { arm_v7s_iopte mask; + phys_addr_t paddr; if (ARM_V7S_PTE_IS_TABLE(pte, lvl)) mask = ARM_V7S_TABLE_MASK; @@ -205,7 +216,14 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl, else mask = ARM_V7S_LVL_MASK(lvl); - return pte & mask; + paddr = pte & mask; + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB) { + if (pte & ARM_V7S_ATTR_MTK_PA_BIT32) + paddr |= BIT_ULL(32); + if (pte & ARM_V7S_ATTR_MTK_PA_BIT33) + paddr |= BIT_ULL(33); + } + return paddr; } static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl, @@ -326,9 +344,6 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl, if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)) pte |= ARM_V7S_ATTR_NS_SECTION; - if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB) - pte |= ARM_V7S_ATTR_MTK_4GB; - return pte; } @@ -515,7 +530,9 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova, if (!(prot & (IOMMU_READ | IOMMU_WRITE))) return 0; - if (WARN_ON(upper_32_bits(iova) || upper_32_bits(paddr))) + if (WARN_ON(upper_32_bits(iova)) || + WARN_ON(upper_32_bits(paddr) && + !(iop->cfg.quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB))) return -ERANGE; ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd); diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 1ddb2b7..aff5004 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -271,7 +271,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom) dom->cfg = (struct io_pgtable_cfg) { .quirks = IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_PERMS | - IO_PGTABLE_QUIRK_TLBI_ON_MAP, + IO_PGTABLE_QUIRK_TLBI_ON_MAP | + IO_PGTABLE_QUIRK_ARM_MTK_4GB, .pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap, .ias = 32, .oas = 32, @@ -279,9 +280,6 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom) .iommu_dev = data->dev, }; - if (data->enable_4GB) - dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_4GB; - dom->iop = alloc_io_pgtable_ops(ARM_V7S, &dom->cfg, data); if (!dom->iop) { dev_err(data->dev, "Failed to alloc io pgtable\n"); @@ -367,12 +365,16 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); + struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); unsigned long flags; int ret; + /* The "4GB mode" M4U physically can not use the lower remap of Dram. */ + if (data->plat_data->has_4gb_mode && data->enable_4GB) + paddr |= BIT_ULL(32); + spin_lock_irqsave(&dom->pgtlock, flags); - ret = dom->iop->map(dom->iop, iova, paddr & DMA_BIT_MASK(32), - size, prot); + ret = dom->iop->map(dom->iop, iova, paddr, size, prot); spin_unlock_irqrestore(&dom->pgtlock, flags); return ret; @@ -401,7 +403,6 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); - struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); unsigned long flags; phys_addr_t pa; @@ -409,9 +410,6 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, pa = dom->iop->iova_to_phys(dom->iop, iova); spin_unlock_irqrestore(&dom->pgtlock, flags); - if (data->enable_4GB) - pa |= BIT_ULL(32); - return pa; } @@ -742,10 +740,12 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev) static const struct mtk_iommu_plat_data mt2712_data = { .m4u_plat = M4U_MT2712, + .has_4gb_mode = true, }; static const struct mtk_iommu_plat_data mt8173_data = { .m4u_plat = M4U_MT8173, + .has_4gb_mode = true, }; static const struct of_device_id mtk_iommu_of_ids[] = { diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index 483d210..d7a001a 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h @@ -42,6 +42,7 @@ enum mtk_iommu_plat { struct mtk_iommu_plat_data { enum mtk_iommu_plat m4u_plat; + bool has_4gb_mode; }; struct mtk_iommu_domain; -- 1.9.1