[PATCH 1/4] ARC: DTS: mark DMA devices connected through IOC port as dma-coherent
Mark DMA devices on AXS103 and HSDK boards connected through IOC port as dma-coherent. Signed-off-by: Eugeniy Paltsev --- arch/arc/boot/dts/axc003.dtsi | 26 ++ arch/arc/boot/dts/axc003_idu.dtsi | 26 ++ arch/arc/boot/dts/hsdk.dts| 4 3 files changed, 56 insertions(+) diff --git a/arch/arc/boot/dts/axc003.dtsi b/arch/arc/boot/dts/axc003.dtsi index dc91c663bcc0..d75d65ddf8e3 100644 --- a/arch/arc/boot/dts/axc003.dtsi +++ b/arch/arc/boot/dts/axc003.dtsi @@ -93,6 +93,32 @@ }; }; + /* +* Mark DMA peripherals connected via IOC port as dma-coherent. We do +* it via overlay because peripherals defined in axs10x_mb.dtsi are +* used for both AXS101 and AXS103 boards and only AXS103 has IOC (so +* only AXS103 board has HW-coherent DMA peripherals) +* We don't need to mark pgu@17000 as dma-coherent because it uses +* external DMA buffer located outside of IOC aperture. +*/ + axs10x_mb { + ethernet@0x18000 { + dma-coherent; + }; + + ehci@0x4 { + dma-coherent; + }; + + ohci@0x6 { + dma-coherent; + }; + + mmc@0x15000 { + dma-coherent; + }; + }; + /* * The DW APB ICTL intc on MB is connected to CPU intc via a * DT "invisible" DW APB GPIO block, configured to simply pass thru diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi index 69ff4895f2ba..a05bb737ea63 100644 --- a/arch/arc/boot/dts/axc003_idu.dtsi +++ b/arch/arc/boot/dts/axc003_idu.dtsi @@ -100,6 +100,32 @@ }; }; + /* +* Mark DMA peripherals connected via IOC port as dma-coherent. We do +* it via overlay because peripherals defined in axs10x_mb.dtsi are +* used for both AXS101 and AXS103 boards and only AXS103 has IOC (so +* only AXS103 board has HW-coherent DMA peripherals) +* We don't need to mark pgu@17000 as dma-coherent because it uses +* external DMA buffer located outside of IOC aperture. +*/ + axs10x_mb { + ethernet@0x18000 { + dma-coherent; + }; + + ehci@0x4 { + dma-coherent; + }; + + ohci@0x6 { + dma-coherent; + }; + + mmc@0x15000 { + dma-coherent; + }; + }; + /* * This INTC is actually connected to DW APB GPIO * which acts as a wire between MB INTC and CPU INTC. diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts index 006aa3de5348..ebb686c21393 100644 --- a/arch/arc/boot/dts/hsdk.dts +++ b/arch/arc/boot/dts/hsdk.dts @@ -176,6 +176,7 @@ phy-handle = <&phy0>; resets = <&cgu_rst HSDK_ETH_RESET>; reset-names = "stmmaceth"; + dma-coherent; mdio { #address-cells = <1>; @@ -194,12 +195,14 @@ compatible = "snps,hsdk-v1.0-ohci", "generic-ohci"; reg = <0x6 0x100>; interrupts = <15>; + dma-coherent; }; ehci@4 { compatible = "snps,hsdk-v1.0-ehci", "generic-ehci"; reg = <0x4 0x100>; interrupts = <15>; + dma-coherent; }; mmc@a000 { @@ -212,6 +215,7 @@ clock-names = "biu", "ciu"; interrupts = <12>; bus-width = <4>; + dma-coherent; }; }; -- 2.14.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 2/4] ARC: allow to use IOC and non-IOC DMA devices simultaneously
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 --- 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 ..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 N
[PATCH 3/4] ARC: refactor arch/arc/mm/dma.c
Refactoring, no functional change intended. Signed-off-by: Eugeniy Paltsev --- arch/arc/mm/dma.c | 28 ++-- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index b693818cd8e5..46584c7c2858 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -27,30 +27,24 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, struct page *page; phys_addr_t paddr; void *kvaddr; - int need_coh = 1, need_kvaddr = 0; + bool need_coh = !(attrs & DMA_ATTR_NON_CONSISTENT); page = alloc_pages(gfp, order); if (!page) return NULL; - if (attrs & DMA_ATTR_NON_CONSISTENT) - need_coh = 0; - - /* -* - A coherent buffer needs MMU mapping to enforce non-cachability -* - A highmem page needs a virtual handle (hence MMU mapping) -* independent of cachability -*/ - if (PageHighMem(page) || need_coh) - need_kvaddr = 1; - /* This is linear addr (0x8000_ based) */ paddr = page_to_phys(page); *dma_handle = paddr; - /* This is kernel Virtual address (0x7000_ based) */ - if (need_kvaddr) { + /* +* - A coherent buffer needs MMU mapping to enforce non-cachability +* - A highmem page needs a virtual handle (hence MMU mapping) +* independent of cachability. +* kvaddr is kernel Virtual address (0x7000_ based) +*/ + if (PageHighMem(page) || need_coh) { kvaddr = ioremap_nocache(paddr, size); if (kvaddr == NULL) { __free_pages(page, order); @@ -81,11 +75,9 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr, { phys_addr_t paddr = dma_handle; struct page *page = virt_to_page(paddr); - int is_non_coh = 1; - - is_non_coh = (attrs & DMA_ATTR_NON_CONSISTENT); + bool is_coh = !(attrs & DMA_ATTR_NON_CONSISTENT); - if (PageHighMem(page) || !is_non_coh) + if (PageHighMem(page) || is_coh) iounmap((void __force __iomem *)vaddr); __free_pages(page, get_order(size)); -- 2.14.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 0/4] ARC: allow to use IOC and non-IOC DMA devices simultaneously
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. NOTE: This patch series was stress tested on HSDK with iperf3 (ethernet) and bonie++ (usb and sdio). NOTE: If you want to test some device without IOC it is not enough to remove "dma-coherent" property from dts. You had to remap this device to regular DDR AXI port intead of IOC AXI port. You also need to take into account that all DMA devices on ARC will not work without IOC after commit: a8eb92d02dd7 - arc: fix arc_dma_{map,unmap}_page (I will create fix soon, see STAR 9001374807) NOTE: We don't touch any aperture configuration in this patch series. So we don't switch any devices between IOC and non-IOC AXI ports on any board. It can be done later if it is required. Eugeniy Paltsev (4): ARC: DTS: mark DMA devices connected through IOC port as dma-coherent ARC: allow to use IOC and non-IOC DMA devices simultaneously ARC: refactor arch/arc/mm/dma.c ARC: IOC: panic if both IOC and ZONE_HIGHMEM enabled arch/arc/Kconfig | 1 + arch/arc/boot/dts/axc003.dtsi | 26 + arch/arc/boot/dts/axc003_idu.dtsi | 26 + arch/arc/boot/dts/hsdk.dts | 4 +++ arch/arc/include/asm/dma-mapping.h | 13 + arch/arc/mm/cache.c| 30 ++-- arch/arc/mm/dma.c | 58 ++ 7 files changed, 112 insertions(+), 46 deletions(-) create mode 100644 arch/arc/include/asm/dma-mapping.h -- 2.14.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 4/4] ARC: IOC: panic if both IOC and ZONE_HIGHMEM enabled
Signed-off-by: Eugeniy Paltsev --- arch/arc/mm/cache.c | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 34935ce38631..e0b3484641c3 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -1143,6 +1143,19 @@ noinline void __init arc_ioc_setup(void) { unsigned int ioc_base, mem_sz; + /* +* As for today we don't support both IOC and ZONE_HIGHMEM enabled +* simultaneously. This happens because as of today IOC aperture covers +* only ZONE_NORMAL (low mem) and any dma transactions outside this +* region won't be HW coherent. +* If we want to use both IOC and ZONE_HIGHMEM we can use +* bounce_buffer to handle dma transactions to HIGHMEM. +* Also it is possible to modify dma_direct cache ops or increase IOC +* aperture size if we are planning to use HIGHMEM without PAE. +*/ + if (IS_ENABLED(CONFIG_HIGHMEM)) + panic("IOC and HIGHMEM can't be used simultaneously"); + /* Flush + invalidate + disable L1 dcache */ __dc_disable(); -- 2.14.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH RESEND] ARC: Add Ofer Levi as plat-eznps maintainer
From: Leon Romanovsky Signed-off-by: Leon Romanovsky --- Resend with proper Vineet's email --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index c79f306a936a..6be664ed0527 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5444,6 +5444,7 @@ F:drivers/iommu/exynos-iommu.c EZchip NPS platform support M: Vineet Gupta +M: Ofer Levi S: Supported F: arch/arc/plat-eznps F: arch/arc/boot/dts/eznps.dts -- 2.14.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH] ARC: fix broken noncoherent cache ops
All DMA devices on ARC haven't worked with SW cache control since commit a8eb92d02dd7 ("arc: fix arc_dma_{map,unmap}_page") This happens because we don't check direction argument at all in new implementation. Fix that. Fixies: commit a8eb92d02dd7 ("arc: fix arc_dma_{map,unmap}_page") Signed-off-by: Eugeniy Paltsev --- NOTE: * This patch was stress tested on HSDK with bonie++ (usb and sdio) with IOC disabled. The ethernet wasn't tested because it doesn't work with SW cache control as for today (see STAR 9001336019) arch/arc/mm/dma.c | 46 -- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 8c1071840979..cefb776a99ff 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -129,14 +129,56 @@ int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } +/* + * Cache operations depending on function and direction argument, inspired by + * https://lkml.org/lkml/2018/5/18/979 + * "dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20] + * dma-mapping: provide a generic dma-noncoherent implementation)" + * + * | map == for_device | unmap == for_cpu + * | + * TO_DEV | writebackwriteback | none none + * FROM_DEV | invalidate invalidate | invalidateinvalidate + * BIDIR| writeback+invwriteback+inv | invalidateinvalidate + * + * NOTE: we don't check the validity of direction argument as it is done in + * upper layer functions (in include/linux/dma-mapping.h) + */ + void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir) { - dma_cache_wback(paddr, size); + switch (dir) { + case DMA_TO_DEVICE: + dma_cache_wback(paddr, size); + break; + + case DMA_FROM_DEVICE: + dma_cache_inv(paddr, size); + break; + + case DMA_BIDIRECTIONAL: + dma_cache_wback_inv(paddr, size); + break; + + default: + break; + } } void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir) { - dma_cache_inv(paddr, size); + switch (dir) { + case DMA_TO_DEVICE: + break; + + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + dma_cache_inv(paddr, size); + break; + + default: + break; + } } -- 2.14.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH] ARC: fix broken noncoherent cache ops
On 07/24/2018 07:13 AM, Eugeniy Paltsev wrote: > All DMA devices on ARC haven't worked with SW cache control > since commit a8eb92d02dd7 ("arc: fix arc_dma_{map,unmap}_page") > This happens because we don't check direction argument at all in > new implementation. Fix that. Good find and I presume painful to debug. Interesting though how the error tricked finally as the root cause was arc_dma_sync_single*() were broken to begin with. Prior to common ops rework, arc_dma_sync_single_for_device() would unconditionally do cache wback, independent of the direction (by calling _dma_cache_sync helper with TO_DEVICE). In 713a74624bba ("arc: simplify arc_dma_sync_single_for_{cpu,device}") Christoph changed this to skip the helper. And then in a8eb92d02dd7, the usage of these routines was prolifirated to the more common kernel API dma_*map_page() API and that is where the original deficiency showed up. I'll add this bit of history to changelog to remember this better. > Fixies: commit a8eb92d02dd7 ("arc: fix arc_dma_{map,unmap}_page") > Signed-off-by: Eugeniy Paltsev > --- > NOTE: > * This patch was stress tested on HSDK with bonie++ (usb and sdio) >with IOC disabled. The ethernet wasn't tested because it doesn't >work with SW cache control as for today (see STAR 9001336019) > > arch/arc/mm/dma.c | 46 -- > 1 file changed, 44 insertions(+), 2 deletions(-) > > diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c > index 8c1071840979..cefb776a99ff 100644 > --- a/arch/arc/mm/dma.c > +++ b/arch/arc/mm/dma.c > @@ -129,14 +129,56 @@ int arch_dma_mmap(struct device *dev, struct > vm_area_struct *vma, > return ret; > } > > +/* > + * Cache operations depending on function and direction argument, inspired by > + * https://lkml.org/lkml/2018/5/18/979 > + * "dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20] > + * dma-mapping: provide a generic dma-noncoherent implementation)" > + * > + * | map == for_device | unmap == for_cpu > + * | > + * TO_DEV | writebackwriteback | none none > + * FROM_DEV | invalidate invalidate | invalidateinvalidate > + * BIDIR| writeback+invwriteback+inv | invalidateinvalidate > + * > + * NOTE: we don't check the validity of direction argument as it is done in > + * upper layer functions (in include/linux/dma-mapping.h) > + */ > + Very nice ! Added to for-curr Thx, -Vineet > void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, > size_t size, enum dma_data_direction dir) > { > - dma_cache_wback(paddr, size); > + switch (dir) { > + case DMA_TO_DEVICE: > + dma_cache_wback(paddr, size); > + break; > + > + case DMA_FROM_DEVICE: > + dma_cache_inv(paddr, size); > + break; > + > + case DMA_BIDIRECTIONAL: > + dma_cache_wback_inv(paddr, size); > + break; > + > + default: > + break; > + } > } > > void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, > size_t size, enum dma_data_direction dir) > { > - dma_cache_inv(paddr, size); > + switch (dir) { > + case DMA_TO_DEVICE: > + break; > + > + case DMA_FROM_DEVICE: > + case DMA_BIDIRECTIONAL: > + dma_cache_inv(paddr, size); > + break; > + > + default: > + break; > + } > } ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH] ARC: dma [non IOC]: fix arc_dma_sync_single_for_(device|cpu)
From: Eugeniy Paltsev ARC backend for dma_sync_single_for_(device|cpu) was broken as it was not honoring the @dir argument and simply forcing it based on the call: - arc_dma_sync_single_for_device(dir) assumed DMA_TO_DEVICE (cache wback) - arc_dma_sync_single_for_cpu(dir) assumed DMA_FROM_DEVICE (cache inv) This is not true given the DMA API programming model and has been discussed here [1] in some detail. Interestingly while the deficiency has been there forever, it only started showing up after 4.17 dma common ops rework, commit a8eb92d02dd7 ("arc: fix arc_dma_{map,unmap}_page") which wired up these calls under the more commonly used dma_map_page API triggering the issue. [1]: https://lkml.org/lkml/2018/5/18/979 Fixes: commit a8eb92d02dd7 ("arc: fix arc_dma_{map,unmap}_page") Signed-off-by: Eugeniy Paltsev Signed-off-by: Vineet Gupta [vgupta: reworked changelog] Signed-off-by: Vineet Gupta --- This needs to be added to stable 4.17 but Cc with "4.17+" was causing git-send-email issues. --- arch/arc/mm/dma.c | 46 -- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 8c1071840979..cefb776a99ff 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -129,14 +129,56 @@ int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } +/* + * Cache operations depending on function and direction argument, inspired by + * https://lkml.org/lkml/2018/5/18/979 + * "dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20] + * dma-mapping: provide a generic dma-noncoherent implementation)" + * + * | map == for_device | unmap == for_cpu + * | + * TO_DEV | writebackwriteback | none none + * FROM_DEV | invalidate invalidate | invalidateinvalidate + * BIDIR| writeback+invwriteback+inv | invalidateinvalidate + * + * NOTE: we don't check the validity of direction argument as it is done in + * upper layer functions (in include/linux/dma-mapping.h) + */ + void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir) { - dma_cache_wback(paddr, size); + switch (dir) { + case DMA_TO_DEVICE: + dma_cache_wback(paddr, size); + break; + + case DMA_FROM_DEVICE: + dma_cache_inv(paddr, size); + break; + + case DMA_BIDIRECTIONAL: + dma_cache_wback_inv(paddr, size); + break; + + default: + break; + } } void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, size_t size, enum dma_data_direction dir) { - dma_cache_inv(paddr, size); + switch (dir) { + case DMA_TO_DEVICE: + break; + + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + dma_cache_inv(paddr, size); + break; + + default: + break; + } } -- 2.7.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 2/4] arc: fix type warnings in arc/mm/cache.c
From: Randy Dunlap ../arch/arc/mm/cache.c: In function 'flush_anon_page': ../arch/arc/mm/cache.c:1062:55: warning: passing argument 2 of '__flush_dcache_page' makes integer from pointer without a cast [-Wint-conversion] __flush_dcache_page((phys_addr_t)page_address(page), page_address(page)); ^~ ../arch/arc/mm/cache.c:1013:59: note: expected 'long unsigned int' but argument is of type 'void *' void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr) ~~^ Signed-off-by: Randy Dunlap Cc: Vineet Gupta Cc: Ofer Levi Cc: linux-snps-arc@lists.infradead.org --- arch/arc/mm/cache.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) --- linux-next-20180723.orig/arch/arc/mm/cache.c +++ linux-next-20180723/arch/arc/mm/cache.c @@ -1038,7 +1038,7 @@ void flush_cache_mm(struct mm_struct *mm void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr, unsigned long pfn) { - unsigned int paddr = pfn << PAGE_SHIFT; + phys_addr_t paddr = pfn << PAGE_SHIFT; u_vaddr &= PAGE_MASK; @@ -1058,8 +1058,9 @@ void flush_anon_page(struct vm_area_stru unsigned long u_vaddr) { /* TBD: do we really need to clear the kernel mapping */ - __flush_dcache_page(page_address(page), u_vaddr); - __flush_dcache_page(page_address(page), page_address(page)); + __flush_dcache_page((phys_addr_t)page_address(page), u_vaddr); + __flush_dcache_page((phys_addr_t)page_address(page), + (phys_addr_t)page_address(page)); } @@ -1084,7 +1085,7 @@ void copy_user_highpage(struct page *to, * addr_not_cache_congruent() is 0 */ if (page_mapcount(from) && addr_not_cache_congruent(kfrom, u_vaddr)) { - __flush_dcache_page((unsigned long)kfrom, u_vaddr); + __flush_dcache_page((phys_addr_t)kfrom, u_vaddr); clean_src_k_mappings = 1; } @@ -1105,7 +1106,7 @@ void copy_user_highpage(struct page *to, * sync the kernel mapping back to physical page */ if (clean_src_k_mappings) { - __flush_dcache_page((unsigned long)kfrom, (unsigned long)kfrom); + __flush_dcache_page((phys_addr_t)kfrom, (unsigned long)kfrom); set_bit(PG_dc_clean, &from->flags); } else { clear_bit(PG_dc_clean, &from->flags); ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 4/4] arc: fix mtm.c printk format warning
From: Randy Dunlap Fix printk format warning in arch/arc/plat-eznps/mtm.c: In file included from ../include/linux/printk.h:7, from ../include/linux/kernel.h:14, from ../include/linux/list.h:9, from ../include/linux/smp.h:12, from ../arch/arc/plat-eznps/mtm.c:17: ../arch/arc/plat-eznps/mtm.c: In function 'set_mtm_hs_ctr': ../include/linux/kern_levels.h:5:18: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=] #define KERN_SOH "\001" /* ASCII Start Of Header */ ^~ ../include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH' #define KERN_ERR KERN_SOH "3" /* error conditions */ ^~~~ ../include/linux/printk.h:308:9: note: in expansion of macro 'KERN_ERR' printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) ^~~~ ../arch/arc/plat-eznps/mtm.c:166:3: note: in expansion of macro 'pr_err' pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n", ^~ ../arch/arc/plat-eznps/mtm.c:166:40: note: format string is defined here pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n", ~^ %ld The hs_ctr variable can just be int instead of long, so also change kstrtol() to kstrtoint() and leave the format string as %d. Also add 2 header files since they are used in mtm.c and we prefer not to depend on accidental/indirect #includes. Signed-off-by: Randy Dunlap Cc: Vineet Gupta Cc: Ofer Levi Cc: linux-snps-arc@lists.infradead.org --- arch/arc/plat-eznps/mtm.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) --- linux-next-20180723.orig/arch/arc/plat-eznps/mtm.c +++ linux-next-20180723/arch/arc/plat-eznps/mtm.c @@ -15,6 +15,8 @@ */ #include +#include +#include #include #include #include @@ -157,10 +159,10 @@ void mtm_enable_core(unsigned int cpu) /* Verify and set the value of the mtm hs counter */ static int __init set_mtm_hs_ctr(char *ctr_str) { - long hs_ctr; + int hs_ctr; int ret; - ret = kstrtol(ctr_str, 0, &hs_ctr); + ret = kstrtoint(ctr_str, 0, &hs_ctr); if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) { pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n", ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 3/4] arc: fix some plat-eznps data type errors
From: Randy Dunlap Add to fix build errors. Both ctop.h and use u32 types and cause many errors. Examples: ../include/soc/nps/common.h:71:4: error: unknown type name 'u32' u32 __reserved:20, cluster:4, core:4, thread:4; ../include/soc/nps/common.h:76:3: error: unknown type name 'u32' u32 value; ../include/soc/nps/common.h:124:4: error: unknown type name 'u32' u32 base:8, cl_x:4, cl_y:4, ../include/soc/nps/common.h:127:3: error: unknown type name 'u32' u32 value; ../arch/arc/plat-eznps/include/plat/ctop.h:83:4: error: unknown type name 'u32' u32 gen:1, gdis:1, clk_gate_dis:1, asb:1, ../arch/arc/plat-eznps/include/plat/ctop.h:86:3: error: unknown type name 'u32' u32 value; ../arch/arc/plat-eznps/include/plat/ctop.h:93:4: error: unknown type name 'u32' u32 csa:22, dmsid:6, __reserved:3, cs:1; ../arch/arc/plat-eznps/include/plat/ctop.h:95:3: error: unknown type name 'u32' u32 value; Signed-off-by: Randy Dunlap Cc: Vineet Gupta Cc: Ofer Levi Cc: linux-snps-arc@lists.infradead.org --- arch/arc/plat-eznps/include/plat/ctop.h |1 + 1 file changed, 1 insertion(+) --- linux-next-20180723.orig/arch/arc/plat-eznps/include/plat/ctop.h +++ linux-next-20180723/arch/arc/plat-eznps/include/plat/ctop.h @@ -21,6 +21,7 @@ #error "Incorrect ctop.h include" #endif +#include #include /* core auxiliary registers */ ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH 1/4] arc: fix some build issues in delay.h
From: Randy Dunlap Fix build errors in arch/arc/'s delay.h: - add for loops_per_jiffy - add for "u64" In file included from ../drivers/infiniband/hw/cxgb3/cxio_hal.c:32: ../arch/arc/include/asm/delay.h: In function '__udelay': ../arch/arc/include/asm/delay.h:61:12: error: 'u64' undeclared (first use in this function) loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; ^~~ In file included from ../drivers/infiniband/hw/cxgb3/cxio_hal.c:32: ../arch/arc/include/asm/delay.h: In function '__udelay': ../arch/arc/include/asm/delay.h:63:37: error: 'loops_per_jiffy' undeclared (first use in this function) loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; ^~~ Signed-off-by: Randy Dunlap Cc: Vineet Gupta Cc: Ofer Levi Cc: linux-snps-arc@lists.infradead.org --- arch/arc/include/asm/delay.h |2 ++ 1 file changed, 2 insertions(+) --- linux-next-20180723.orig/arch/arc/include/asm/delay.h +++ linux-next-20180723/arch/arc/include/asm/delay.h @@ -17,6 +17,8 @@ #ifndef __ASM_ARC_UDELAY_H #define __ASM_ARC_UDELAY_H +#include +#include #include /* HZ */ static inline void __delay(unsigned long loops) ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
arc: some allmodconfig fixup patches
From: Randy Dunlap Hi, Here are a few patches that fix build errors or warnings that I encountered while doing arc "allmodconfig" builds. These patches do not fix all of the build issues. arch/arc/include/asm/delay.h|2 ++ arch/arc/mm/cache.c | 11 ++- arch/arc/plat-eznps/include/plat/ctop.h |1 + arch/arc/plat-eznps/mtm.c |6 -- 4 files changed, 13 insertions(+), 7 deletions(-) ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH 1/4] arc: fix some build issues in delay.h
On 07/24/2018 01:46 PM, Randy Dunlap wrote: > From: Randy Dunlap > > Fix build errors in arch/arc/'s delay.h: > - add for loops_per_jiffy > - add for "u64" > > In file included from ../drivers/infiniband/hw/cxgb3/cxio_hal.c:32: > ../arch/arc/include/asm/delay.h: In function '__udelay': > ../arch/arc/include/asm/delay.h:61:12: error: 'u64' undeclared (first use in > this function) > loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; > ^~~ > > In file included from ../drivers/infiniband/hw/cxgb3/cxio_hal.c:32: > ../arch/arc/include/asm/delay.h: In function '__udelay': > ../arch/arc/include/asm/delay.h:63:37: error: 'loops_per_jiffy' undeclared > (first use in this function) > loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; > ^~~ > > Signed-off-by: Randy Dunlap > Cc: Vineet Gupta > Cc: Ofer Levi > Cc: linux-snps-arc@lists.infradead.org > --- > arch/arc/include/asm/delay.h |2 ++ > 1 file changed, 2 insertions(+) > > --- linux-next-20180723.orig/arch/arc/include/asm/delay.h > +++ linux-next-20180723/arch/arc/include/asm/delay.h > @@ -17,6 +17,8 @@ > #ifndef __ASM_ARC_UDELAY_H > #define __ASM_ARC_UDELAY_H > > +#include this file in turn includes asm/delay.h - the header guards will catch nested inclusion still seems ugly. Should we just reference loops_per_jiffy here like other arches do in theur delay.h > +#include > #include/* HZ */ > > static inline void __delay(unsigned long loops) > ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH 1/4] arc: fix some build issues in delay.h
On 07/24/2018 03:04 PM, Vineet Gupta wrote: > On 07/24/2018 01:46 PM, Randy Dunlap wrote: >> From: Randy Dunlap >> >> Fix build errors in arch/arc/'s delay.h: >> - add for loops_per_jiffy >> - add for "u64" >> >> In file included from ../drivers/infiniband/hw/cxgb3/cxio_hal.c:32: >> ../arch/arc/include/asm/delay.h: In function '__udelay': >> ../arch/arc/include/asm/delay.h:61:12: error: 'u64' undeclared (first use in >> this function) >> loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; >> ^~~ >> >> In file included from ../drivers/infiniband/hw/cxgb3/cxio_hal.c:32: >> ../arch/arc/include/asm/delay.h: In function '__udelay': >> ../arch/arc/include/asm/delay.h:63:37: error: 'loops_per_jiffy' undeclared >> (first use in this function) >> loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; >> ^~~ >> >> Signed-off-by: Randy Dunlap >> Cc: Vineet Gupta >> Cc: Ofer Levi >> Cc: linux-snps-arc@lists.infradead.org >> --- >> arch/arc/include/asm/delay.h |2 ++ >> 1 file changed, 2 insertions(+) >> >> --- linux-next-20180723.orig/arch/arc/include/asm/delay.h >> +++ linux-next-20180723/arch/arc/include/asm/delay.h >> @@ -17,6 +17,8 @@ >> #ifndef __ASM_ARC_UDELAY_H >> #define __ASM_ARC_UDELAY_H >> >> +#include > > this file in turn includes asm/delay.h - the header guards will catch nested > inclusion still seems ugly. Should we just reference loops_per_jiffy here like > other arches do in theur delay.h Yes, that's a good idea. I'll do that. >> +#include >> #include /* HZ */ >> >> static inline void __delay(unsigned long loops) >> > -- ~Randy ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH 2/4] arc: fix type warnings in arc/mm/cache.c
On 07/24/2018 01:46 PM, Randy Dunlap wrote: > From: Randy Dunlap > > ../arch/arc/mm/cache.c: In function 'flush_anon_page': > ../arch/arc/mm/cache.c:1062:55: warning: passing argument 2 of > '__flush_dcache_page' makes integer from pointer without a cast > [-Wint-conversion] > __flush_dcache_page((phys_addr_t)page_address(page), page_address(page)); >^~ > ../arch/arc/mm/cache.c:1013:59: note: expected 'long unsigned int' but > argument is of type 'void *' > void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr) > ~~^ > > Signed-off-by: Randy Dunlap > Cc: Vineet Gupta > Cc: Ofer Levi > Cc: linux-snps-arc@lists.infradead.org > --- > arch/arc/mm/cache.c | 11 ++- > 1 file changed, 6 insertions(+), 5 deletions(-) > > --- linux-next-20180723.orig/arch/arc/mm/cache.c > +++ linux-next-20180723/arch/arc/mm/cache.c > @@ -1038,7 +1038,7 @@ void flush_cache_mm(struct mm_struct *mm > void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr, > unsigned long pfn) > { > - unsigned int paddr = pfn << PAGE_SHIFT; > + phys_addr_t paddr = pfn << PAGE_SHIFT; > > u_vaddr &= PAGE_MASK; > > @@ -1058,8 +1058,9 @@ void flush_anon_page(struct vm_area_stru >unsigned long u_vaddr) > { > /* TBD: do we really need to clear the kernel mapping */ > - __flush_dcache_page(page_address(page), u_vaddr); > - __flush_dcache_page(page_address(page), page_address(page)); > + __flush_dcache_page((phys_addr_t)page_address(page), u_vaddr); > + __flush_dcache_page((phys_addr_t)page_address(page), > + (phys_addr_t)page_address(page)); CONFIG_ARC_CACHE_VIPT_ALIASING is a total bitrot and I'm considering removing it as no sane systems should use it. There's none which I know are using it. But for now this will do. > > } > > @@ -1084,7 +1085,7 @@ void copy_user_highpage(struct page *to, >* addr_not_cache_congruent() is 0 >*/ > if (page_mapcount(from) && addr_not_cache_congruent(kfrom, u_vaddr)) { > - __flush_dcache_page((unsigned long)kfrom, u_vaddr); > + __flush_dcache_page((phys_addr_t)kfrom, u_vaddr); Was this needed really ? I can't seem to trigger any warnings here. All of this (original code before your change) is technically incorrect due to the combination of CONFIG_ARC_CACHE_VIPT_ALIASING and CONFIG_HIGHMEM. @kfrom is returned by kmap_atomic() and in highmem regime it could be a kernel virtual address, so calling the low level cache flush interface with a kvaddr, pretending it is paddr (whethe runsigned long or phys_addr_t) is just not right. This combinations needs to be disallowed from Kconfig ! > clean_src_k_mappings = 1; > } > > @@ -1105,7 +1106,7 @@ void copy_user_highpage(struct page *to, >* sync the kernel mapping back to physical page >*/ > if (clean_src_k_mappings) { > - __flush_dcache_page((unsigned long)kfrom, (unsigned long)kfrom); > + __flush_dcache_page((phys_addr_t)kfrom, (unsigned long)kfrom); > set_bit(PG_dc_clean, &from->flags); > } else { > clear_bit(PG_dc_clean, &from->flags); > Ditto ! ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH 2/4] arc: fix type warnings in arc/mm/cache.c
On 07/24/2018 05:02 PM, Vineet Gupta wrote: > On 07/24/2018 01:46 PM, Randy Dunlap wrote: >> From: Randy Dunlap >> >> ../arch/arc/mm/cache.c: In function 'flush_anon_page': >> ../arch/arc/mm/cache.c:1062:55: warning: passing argument 2 of >> '__flush_dcache_page' makes integer from pointer without a cast >> [-Wint-conversion] >> __flush_dcache_page((phys_addr_t)page_address(page), page_address(page)); >>^~ >> ../arch/arc/mm/cache.c:1013:59: note: expected 'long unsigned int' but >> argument is of type 'void *' >> void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr) >> ~~^ >> >> Signed-off-by: Randy Dunlap >> Cc: Vineet Gupta >> Cc: Ofer Levi >> Cc: linux-snps-arc@lists.infradead.org >> --- >> arch/arc/mm/cache.c | 11 ++- >> 1 file changed, 6 insertions(+), 5 deletions(-) >> >> --- linux-next-20180723.orig/arch/arc/mm/cache.c >> +++ linux-next-20180723/arch/arc/mm/cache.c >> @@ -1038,7 +1038,7 @@ void flush_cache_mm(struct mm_struct *mm >> void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr, >>unsigned long pfn) >> { >> -unsigned int paddr = pfn << PAGE_SHIFT; >> +phys_addr_t paddr = pfn << PAGE_SHIFT; >> >> u_vaddr &= PAGE_MASK; >> >> @@ -1058,8 +1058,9 @@ void flush_anon_page(struct vm_area_stru >> unsigned long u_vaddr) >> { >> /* TBD: do we really need to clear the kernel mapping */ >> -__flush_dcache_page(page_address(page), u_vaddr); >> -__flush_dcache_page(page_address(page), page_address(page)); >> +__flush_dcache_page((phys_addr_t)page_address(page), u_vaddr); >> +__flush_dcache_page((phys_addr_t)page_address(page), >> +(phys_addr_t)page_address(page)); > > CONFIG_ARC_CACHE_VIPT_ALIASING is a total bitrot and I'm considering removing > it > as no sane systems should use it. There's none which I know are using it. > But for now this will do. > > >> >> } >> >> @@ -1084,7 +1085,7 @@ void copy_user_highpage(struct page *to, >> * addr_not_cache_congruent() is 0 >> */ >> if (page_mapcount(from) && addr_not_cache_congruent(kfrom, u_vaddr)) { >> -__flush_dcache_page((unsigned long)kfrom, u_vaddr); >> +__flush_dcache_page((phys_addr_t)kfrom, u_vaddr); > > Was this needed really ? I can't seem to trigger any warnings here. Nope.. glad you caught that. I can't explain it. :( I can only say that if I had _meant_ to patch that, I would have also included the warning messages from gcc. > All of this (original code before your change) is technically incorrect due > to the > combination of CONFIG_ARC_CACHE_VIPT_ALIASING and CONFIG_HIGHMEM. @kfrom is > returned by kmap_atomic() and in highmem regime it could be a kernel virtual > address, so calling the low level cache flush interface with a kvaddr, > pretending > it is paddr (whethe runsigned long or phys_addr_t) is just not right. This > combinations needs to be disallowed from Kconfig ! > >> clean_src_k_mappings = 1; >> } >> >> @@ -1105,7 +1106,7 @@ void copy_user_highpage(struct page *to, >> * sync the kernel mapping back to physical page >> */ >> if (clean_src_k_mappings) { >> -__flush_dcache_page((unsigned long)kfrom, (unsigned long)kfrom); >> +__flush_dcache_page((phys_addr_t)kfrom, (unsigned long)kfrom); >> set_bit(PG_dc_clean, &from->flags); >> } else { >> clear_bit(PG_dc_clean, &from->flags); >> > > Ditto ! > Thanks. -- ~Randy ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc