// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)3*/45#include <linux/dma-map-ops.h>6#include <asm/cache.h>7#include <asm/cacheflush.h>89/*10* ARCH specific callbacks for generic noncoherent DMA ops11* - hardware IOC not available (or "dma-coherent" not set for device in DT)12* - But still handle both coherent and non-coherent requests from caller13*14* For DMA coherent hardware (IOC) generic code suffices15*/1617void arch_dma_prep_coherent(struct page *page, size_t size)18{19/*20* Evict any existing L1 and/or L2 lines for the backing page21* in case it was used earlier as a normal "cached" page.22* Yeah this bit us - STAR 900089826623*24* Although core does call flush_cache_vmap(), it gets kvaddr hence25* can't be used to efficiently flush L1 and/or L2 which need paddr26* Currently flush_cache_vmap nukes the L1 cache completely which27* will be optimized as a separate commit28*/29dma_cache_wback_inv(page_to_phys(page), size);30}3132/*33* Cache operations depending on function and direction argument, inspired by34* https://lore.kernel.org/lkml/[email protected]35* "dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20]36* dma-mapping: provide a generic dma-noncoherent implementation)"37*38* | map == for_device | unmap == for_cpu39* |----------------------------------------------------------------40* TO_DEV | writeback writeback | none none41* FROM_DEV | invalidate invalidate | invalidate* invalidate*42* BIDIR | writeback+inv writeback+inv | invalidate invalidate43*44* [*] needed for CPU speculative prefetches45*46* NOTE: we don't check the validity of direction argument as it is done in47* upper layer functions (in include/linux/dma-mapping.h)48*/4950void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,51enum dma_data_direction dir)52{53switch (dir) {54case DMA_TO_DEVICE:55dma_cache_wback(paddr, size);56break;5758case DMA_FROM_DEVICE:59dma_cache_inv(paddr, size);60break;6162case DMA_BIDIRECTIONAL:63dma_cache_wback_inv(paddr, size);64break;6566default:67break;68}69}7071void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,72enum dma_data_direction dir)73{74switch (dir) {75case DMA_TO_DEVICE:76break;7778/* FROM_DEVICE invalidate needed if speculative CPU prefetch only */79case DMA_FROM_DEVICE:80case DMA_BIDIRECTIONAL:81dma_cache_inv(paddr, size);82break;8384default:85break;86}87}8889/*90* Plug in direct dma map ops.91*/92void arch_setup_dma_ops(struct device *dev, bool coherent)93{94/*95* IOC hardware snoops all DMA traffic keeping the caches consistent96* with memory - eliding need for any explicit cache maintenance of97* DMA buffers.98*/99if (is_isa_arcv2() && ioc_enable && coherent)100dev->dma_coherent = true;101102dev_info(dev, "use %scoherent DMA ops\n",103dev->dma_coherent ? "" : "non");104}105106107