2014-11-06 15:19:53 +08:00
/*
* Copyright ( C ) 2011 Tobias Klauser < tklauser @ distanz . ch >
* Copyright ( C ) 2009 Wind River Systems Inc
* Implemented by fredrik . markstrom @ gmail . com and ivarholmqvist @ gmail . com
*
* Based on DMA code from MIPS .
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/types.h>
# include <linux/mm.h>
# include <linux/string.h>
# include <linux/dma-mapping.h>
# include <linux/io.h>
# include <linux/cache.h>
# include <asm/cacheflush.h>
2018-04-16 19:27:22 +02:00
void arch_sync_dma_for_device ( struct device * dev , phys_addr_t paddr ,
size_t size , enum dma_data_direction dir )
2016-01-20 15:01:41 -08:00
{
2018-04-16 19:27:22 +02:00
void * vaddr = phys_to_virt ( paddr ) ;
switch ( dir ) {
2016-01-20 15:01:41 -08:00
case DMA_FROM_DEVICE :
invalidate_dcache_range ( ( unsigned long ) vaddr ,
( unsigned long ) ( vaddr + size ) ) ;
break ;
case DMA_TO_DEVICE :
/*
* We just need to flush the caches here , but Nios2 flush
* instruction will do both writeback and invalidate .
*/
case DMA_BIDIRECTIONAL : /* flush and invalidate */
flush_dcache_range ( ( unsigned long ) vaddr ,
( unsigned long ) ( vaddr + size ) ) ;
break ;
default :
BUG ( ) ;
}
}
2014-11-06 15:19:53 +08:00
2018-04-16 19:27:22 +02:00
void arch_sync_dma_for_cpu ( struct device * dev , phys_addr_t paddr ,
size_t size , enum dma_data_direction dir )
2016-01-20 15:01:41 -08:00
{
2018-04-16 19:27:22 +02:00
void * vaddr = phys_to_virt ( paddr ) ;
switch ( dir ) {
2016-01-20 15:01:41 -08:00
case DMA_BIDIRECTIONAL :
case DMA_FROM_DEVICE :
invalidate_dcache_range ( ( unsigned long ) vaddr ,
( unsigned long ) ( vaddr + size ) ) ;
break ;
case DMA_TO_DEVICE :
break ;
default :
BUG ( ) ;
}
}
2019-04-28 14:00:52 -05:00
void arch_dma_prep_coherent ( struct page * page , size_t size )
2014-11-06 15:19:53 +08:00
{
2019-04-28 14:00:52 -05:00
unsigned long start = ( unsigned long ) page_address ( page ) ;
2014-11-06 15:19:53 +08:00
2019-04-28 14:00:52 -05:00
flush_dcache_range ( start , start + size ) ;
}
2014-11-06 15:19:53 +08:00
2019-04-28 14:00:52 -05:00
void * uncached_kernel_address ( void * ptr )
{
unsigned long addr = ( unsigned long ) ptr ;
2014-11-06 15:19:53 +08:00
2019-04-28 14:00:52 -05:00
addr | = CONFIG_NIOS2_IO_REGION_BASE ;
2014-11-06 15:19:53 +08:00
2019-04-28 14:00:52 -05:00
return ( void * ) ptr ;
2014-11-06 15:19:53 +08:00
}
2019-04-28 14:00:52 -05:00
void * cached_kernel_address ( void * ptr )
2014-11-06 15:19:53 +08:00
{
2019-04-28 14:00:52 -05:00
unsigned long addr = ( unsigned long ) ptr ;
addr & = ~ CONFIG_NIOS2_IO_REGION_BASE ;
addr | = CONFIG_NIOS2_KERNEL_REGION_BASE ;
2014-11-06 15:19:53 +08:00
2019-04-28 14:00:52 -05:00
return ( void * ) ptr ;
2014-11-06 15:19:53 +08:00
}