2019-06-03 08:44:50 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-03-05 15:49:30 +04:00
/*
* Copyright ( C ) 2012 ARM Ltd .
* Author : Catalin Marinas < catalin . marinas @ arm . com >
*/
# include <linux/gfp.h>
2016-08-15 09:45:46 +03:00
# include <linux/cache.h>
2020-09-22 16:31:03 +03:00
# include <linux/dma-map-ops.h>
2022-08-16 20:28:04 +03:00
# include <linux/iommu.h>
2019-07-24 15:07:28 +03:00
# include <xen/xen.h>
2012-03-05 15:49:30 +04:00
# include <asm/cacheflush.h>
2022-06-02 22:23:46 +03:00
# include <asm/xen/xen-ops.h>
2012-03-05 15:49:30 +04:00
2019-11-07 20:03:11 +03:00
void arch_sync_dma_for_device ( phys_addr_t paddr , size_t size ,
2022-06-10 18:12:28 +03:00
enum dma_data_direction dir )
2013-05-21 20:35:19 +04:00
{
2022-06-10 18:12:28 +03:00
unsigned long start = ( unsigned long ) phys_to_virt ( paddr ) ;
dcache_clean_poc ( start , start + size ) ;
2013-05-21 20:35:19 +04:00
}
2019-11-07 20:03:11 +03:00
void arch_sync_dma_for_cpu ( phys_addr_t paddr , size_t size ,
2022-06-10 18:12:28 +03:00
enum dma_data_direction dir )
2013-05-21 20:35:19 +04:00
{
2022-06-10 18:12:28 +03:00
unsigned long start = ( unsigned long ) phys_to_virt ( paddr ) ;
if ( dir = = DMA_TO_DEVICE )
return ;
dcache_inval_poc ( start , start + size ) ;
2013-05-21 20:35:19 +04:00
}
2018-11-04 22:29:28 +03:00
void arch_dma_prep_coherent ( struct page * page , size_t size )
{
2022-06-10 18:12:28 +03:00
unsigned long start = ( unsigned long ) page_address ( page ) ;
2023-03-30 18:23:03 +03:00
dcache_clean_poc ( start , start + size ) ;
2018-11-04 22:29:28 +03:00
}
2015-10-01 22:13:59 +03:00
# ifdef CONFIG_IOMMU_DMA
2015-10-01 22:14:00 +03:00
void arch_teardown_dma_ops ( struct device * dev )
{
2017-01-21 00:04:02 +03:00
dev - > dma_ops = NULL ;
2015-10-01 22:14:00 +03:00
}
2019-05-20 10:29:29 +03:00
# endif
2015-10-01 22:13:59 +03:00
2015-10-01 22:14:00 +03:00
void arch_setup_dma_ops ( struct device * dev , u64 dma_base , u64 size ,
2016-04-07 20:42:05 +03:00
const struct iommu_ops * iommu , bool coherent )
2015-10-01 22:14:00 +03:00
{
2019-06-14 16:11:41 +03:00
int cls = cache_line_size_of_cpu ( ) ;
WARN_TAINT ( ! coherent & & cls > ARCH_DMA_MINALIGN ,
TAINT_CPU_OUT_OF_SPEC ,
" %s %s: ARCH_DMA_MINALIGN smaller than CTR_EL0.CWG (%d < %d) " ,
dev_driver_string ( dev ) , dev_name ( dev ) ,
ARCH_DMA_MINALIGN , cls ) ;
2018-10-08 10:12:01 +03:00
dev - > dma_coherent = coherent ;
2019-05-20 10:29:29 +03:00
if ( iommu )
2021-06-18 18:20:59 +03:00
iommu_setup_dma_ops ( dev , dma_base , dma_base + size - 1 ) ;
2017-04-14 00:04:21 +03:00
2022-06-02 22:23:46 +03:00
xen_setup_dma_ops ( dev ) ;
2015-10-01 22:14:00 +03:00
}