From patchwork Tue Jul 24 10:09:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugeniy Paltsev X-Patchwork-Id: 948334 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-snps-arc-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=synopsys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="jiUEuYs0"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=synopsys.com header.i=@synopsys.com header.b="hn4g/CnV"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41ZYz41518z9s8T for ; Tue, 24 Jul 2018 20:10:56 +1000 (AEST) 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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=XBWBilNHE0jzorix/NgMQbwoCWSq9QJFV1+JhheUGJM=; b=jiUEuYs0pvSXKH4uJF3Tfp6uPr 09T078bR8uw9CMBvP7zgoWFRFW64Az3SQtlfsNZsoKWlyuknMZ4QMzSHb0bFjcvDqqo43Zy7mwgHz qfy9AVnqZuDn6qIqG+N3XmfHjZXIKli3ljNOx52nkZkawuAptGppckT0sjBHMB5nVyrmySPGWjLCt qkv2Qnw8CCDd8H6dzig6PEQwsTcSJzms4vAVDNUw4qVVEfrJI/jIUIblsNQsz1dYU3KW5hxpCvCka b+DVR1R/SNaWh0WT5SsP6EbLZlupJkfJ/EWg1uBi0nZThhsDvXrLEjbDfr+z/zdjrGHp5PNQgPD85 3mqtaomg==; 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 1fhuHN-0003NI-Td; Tue, 24 Jul 2018 10:10:53 +0000 Received: from smtprelay2.synopsys.com ([198.182.60.111] helo=smtprelay.synopsys.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fhuHJ-0003IR-73 for linux-snps-arc@lists.infradead.org; Tue, 24 Jul 2018 10:10:52 +0000 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id E9EFE10C0B30; Tue, 24 Jul 2018 03:10:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1532427039; bh=jyT3ex7FyLJrxtqCR19UYjZ6/4R2QkIq0UtgAgSQEB8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hn4g/CnVPR3gDFx6t4mZy/h1/L5y6BtQy0sBvcddxUv9IPGGeLQHUo0pDVnL9/R6d wzjd2Uo1vxYsggH/8qpNZky1C7/PSAnIQk6HITKhcWNs9aIEu7KRqj+ecGl2fWiWDN QqEAgwOZNrLyg3cTb4W5tomZjoUlPPpPW75ENkEhiqheoKLDUgGB1oWOKZ5DzNDajI 0VYB8ICHayN9tpsZ9+bcRWOZEg8b/8CUUTWIvMPGBlzx4Rc5CXLfcRVnFzj9QPBdff 6NbxHK3r/J2zkbdxmKBtygaAm88dhTLlGeiU1dfXNVd47BSezdaB7ewoH6PwrWpYkQ zpC4bbBGgatog== Received: from paltsev-e7480.internal.synopsys.com (unknown [10.121.8.86]) by mailhost.synopsys.com (Postfix) with ESMTP id 3908B3333; Tue, 24 Jul 2018 03:10:38 -0700 (PDT) From: Eugeniy Paltsev To: linux-snps-arc@lists.infradead.org Subject: [PATCH 2/4] ARC: allow to use IOC and non-IOC DMA devices simultaneously Date: Tue, 24 Jul 2018 13:09:59 +0300 Message-Id: <20180724101001.31965-3-Eugeniy.Paltsev@synopsys.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180724101001.31965-1-Eugeniy.Paltsev@synopsys.com> References: <20180724101001.31965-1-Eugeniy.Paltsev@synopsys.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180724_031049_273742_8FCB36A5 X-CRM114-Status: GOOD ( 18.27 ) X-Spam-Score: -0.1 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [198.182.60.111 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-snps-arc@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux on Synopsys ARC Processors List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arch@vger.kernel.org, Vineet Gupta , Alexey Brodkin , linux-kernel@vger.kernel.org, Eugeniy Paltsev , hch@lst.de MIME-Version: 1.0 Sender: "linux-snps-arc" Errors-To: linux-snps-arc-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The ARC HS processor provides an IOC port (I/O coherency bus interface) that allows external devices such as DMA devices to access memory through the cache hierarchy, providing coherency between I/O transactions and the complete memory hierarchy. Some recent SoC with ARC HS (like HSDK) allow to select bus port (IOC or non-IOC port) for connecting DMA devices in runtime. With this patch we can use both HW-coherent and regular DMA peripherals simultaneously. For example we can connect Ethernet and SDIO controllers through IOC port (so we don't need to need to maintain cache coherency for these devices manualy. All cache sync ops will be nop) And we can connect USB directly to RAM port (so we had to maintain cache coherency manualy. Cache sync ops will be real flush/invalidate operations) Cache ops are set per-device and depends on "dma-coherent" device tree property: "dma_noncoherent_ops" are used if no "dma-coherent" property is present (or IOC is disabled) "dma_direct_ops" are used if "dma-coherent" property is present. Signed-off-by: Eugeniy Paltsev Reviewed-by: Christoph Hellwig --- Changes RFC v2 -> PATCH v1: * Move device tree changes to separate patch. Add AXS103 device tree changes. * Don't check IOC status in arch_dma_free function (Thanks to Christoph) * Add panic for IOC + HIGHMEM in separate patch. Changes RFC v1 -> RFC v2 (Thanks to Vineet and Christoph): * Panic if both IOC and HIGHMEM_ZONE are enabled. * Move arch_setup_dma_ops to arch/arc/mm/dma.c * Tweak the boot printing about IOC * Print info about cache ops used for each device. * Refactor arch_setup_dma_ops arch/arc/Kconfig | 1 + arch/arc/include/asm/dma-mapping.h | 13 +++++++++++++ arch/arc/mm/cache.c | 17 ++--------------- arch/arc/mm/dma.c | 34 +++++++++++++++++++--------------- 4 files changed, 35 insertions(+), 30 deletions(-) create mode 100644 arch/arc/include/asm/dma-mapping.h diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index e81bcd271be7..0a2fcd2a8c32 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -17,6 +17,7 @@ config ARC select CLONE_BACKWARDS select COMMON_CLK select DMA_NONCOHERENT_OPS + select DMA_DIRECT_OPS select DMA_NONCOHERENT_MMAP select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC) select GENERIC_CLOCKEVENTS diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h new file mode 100644 index 000000000000..c946c0a83e76 --- /dev/null +++ b/arch/arc/include/asm/dma-mapping.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +// (C) 2018 Synopsys, Inc. (www.synopsys.com) + +#ifndef ASM_ARC_DMA_MAPPING_H +#define ASM_ARC_DMA_MAPPING_H + +#include + +void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, + const struct iommu_ops *iommu, bool coherent); +#define arch_setup_dma_ops arch_setup_dma_ops + +#endif diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 9dbe645ee127..34935ce38631 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -65,7 +65,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) n += scnprintf(buf + n, len - n, "Peripherals\t: %#lx%s%s\n", perip_base, - IS_AVAIL3(ioc_exists, ioc_enable, ", IO-Coherency ")); + IS_AVAIL3(ioc_exists, ioc_enable, ", per device IO-Coherency ")); return buf; } @@ -896,15 +896,6 @@ static void __dma_cache_wback_slc(phys_addr_t start, unsigned long sz) slc_op(start, sz, OP_FLUSH); } -/* - * DMA ops for systems with IOC - * IOC hardware snoops all DMA traffic keeping the caches consistent with - * memory - eliding need for any explicit cache maintenance of DMA buffers - */ -static void __dma_cache_wback_inv_ioc(phys_addr_t start, unsigned long sz) {} -static void __dma_cache_inv_ioc(phys_addr_t start, unsigned long sz) {} -static void __dma_cache_wback_ioc(phys_addr_t start, unsigned long sz) {} - /* * Exported DMA API */ @@ -1253,11 +1244,7 @@ void __init arc_cache_init_master(void) if (is_isa_arcv2() && ioc_enable) arc_ioc_setup(); - if (is_isa_arcv2() && ioc_enable) { - __dma_cache_wback_inv = __dma_cache_wback_inv_ioc; - __dma_cache_inv = __dma_cache_inv_ioc; - __dma_cache_wback = __dma_cache_wback_ioc; - } else if (is_isa_arcv2() && l2_line_sz && slc_enable) { + if (is_isa_arcv2() && l2_line_sz && slc_enable) { __dma_cache_wback_inv = __dma_cache_wback_inv_slc; __dma_cache_inv = __dma_cache_inv_slc; __dma_cache_wback = __dma_cache_wback_slc; diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 8c1071840979..b693818cd8e5 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -33,19 +33,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, if (!page) return NULL; - /* - * IOC relies on all data (even coherent DMA data) being in cache - * Thus allocate normal cached memory - * - * The gains with IOC are two pronged: - * -For streaming data, elides need for cache maintenance, saving - * cycles in flush code, and bus bandwidth as all the lines of a - * buffer need to be flushed out to memory - * -For coherent data, Read/Write to buffers terminate early in cache - * (vs. always going to memory - thus are faster) - */ - if ((is_isa_arcv2() && ioc_enable) || - (attrs & DMA_ATTR_NON_CONSISTENT)) + if (attrs & DMA_ATTR_NON_CONSISTENT) need_coh = 0; /* @@ -95,8 +83,7 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr, struct page *page = virt_to_page(paddr); int is_non_coh = 1; - is_non_coh = (attrs & DMA_ATTR_NON_CONSISTENT) || - (is_isa_arcv2() && ioc_enable); + is_non_coh = (attrs & DMA_ATTR_NON_CONSISTENT); if (PageHighMem(page) || !is_non_coh) iounmap((void __force __iomem *)vaddr); @@ -140,3 +127,20 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, { dma_cache_inv(paddr, size); } + +void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, + const struct iommu_ops *iommu, bool coherent) +{ + /* + * IOC hardware snoops all DMA traffic keeping the caches consistent + * with memory - eliding need for any explicit cache maintenance of + * DMA buffers - so we can use dma_direct cache ops. + */ + if (is_isa_arcv2() && ioc_enable && coherent) { + set_dma_ops(dev, &dma_direct_ops); + dev_info(dev, "use dma_direct_ops cache ops\n"); + } else { + set_dma_ops(dev, &dma_noncoherent_ops); + dev_info(dev, "use dma_noncoherent_ops cache ops\n"); + } +}