2005-04-16 15:20:36 -07:00
/*
2005-11-19 01:40:46 +11:00
* Copyright ( C ) 2004 IBM
*
* Implements the generic device dma API for powerpc .
* the pci and vio busses
2005-04-16 15:20:36 -07:00
*/
2005-11-19 01:40:46 +11:00
# ifndef _ASM_DMA_MAPPING_H
# define _ASM_DMA_MAPPING_H
2007-10-16 14:54:33 -05:00
# ifdef __KERNEL__
# include <linux/types.h>
# include <linux/cache.h>
/* need struct page definitions */
# include <linux/mm.h>
# include <linux/scatterlist.h>
2008-07-05 05:05:42 +10:00
# include <linux/dma-attrs.h>
2009-08-04 19:08:26 +00:00
# include <linux/dma-debug.h>
2007-10-16 14:54:33 -05:00
# include <asm/io.h>
2009-05-14 12:42:28 +00:00
# include <asm/swiotlb.h>
2007-10-16 14:54:33 -05:00
2015-09-09 15:39:46 -07:00
# ifdef CONFIG_PPC64
2007-10-16 14:54:33 -05:00
# define DMA_ERROR_CODE (~(dma_addr_t)0x0)
2015-09-09 15:39:46 -07:00
# endif
2007-10-16 14:54:33 -05:00
2009-05-14 12:42:28 +00:00
/* Some dma direct funcs must be visible for use in other dma_ops */
2015-06-24 15:25:31 +10:00
extern void * __dma_direct_alloc_coherent ( struct device * dev , size_t size ,
dma_addr_t * dma_handle , gfp_t flag ,
struct dma_attrs * attrs ) ;
extern void __dma_direct_free_coherent ( struct device * dev , size_t size ,
void * vaddr , dma_addr_t dma_handle ,
2011-12-06 14:14:46 +01:00
struct dma_attrs * attrs ) ;
2012-06-14 13:03:04 +02:00
extern int dma_direct_mmap_coherent ( struct device * dev ,
struct vm_area_struct * vma ,
void * cpu_addr , dma_addr_t handle ,
size_t size , struct dma_attrs * attrs ) ;
2009-05-14 12:42:28 +00:00
2007-10-16 14:54:33 -05:00
# ifdef CONFIG_NOT_COHERENT_CACHE
/*
* DMA - consistent mapping functions for PowerPCs that don ' t support
* cache snooping . These allocate / free a region of uncached mapped
* memory space for use with DMA devices . Alternatively , you could
* allocate the space " normally " and use the cache management functions
* to ensure it is consistent .
*/
2009-05-27 13:50:33 +10:00
struct device ;
extern void * __dma_alloc_coherent ( struct device * dev , size_t size ,
dma_addr_t * handle , gfp_t gfp ) ;
2007-10-16 14:54:33 -05:00
extern void __dma_free_coherent ( size_t size , void * vaddr ) ;
extern void __dma_sync ( void * vaddr , size_t size , int direction ) ;
extern void __dma_sync_page ( struct page * page , unsigned long offset ,
size_t size , int direction ) ;
2011-03-24 20:50:06 +00:00
extern unsigned long __dma_get_coherent_pfn ( unsigned long cpu_addr ) ;
2007-10-16 14:54:33 -05:00
# else /* ! CONFIG_NOT_COHERENT_CACHE */
/*
* Cache coherent cores .
*/
2009-05-27 13:50:33 +10:00
# define __dma_alloc_coherent(dev, gfp, size, handle) NULL
2007-10-16 14:54:33 -05:00
# define __dma_free_coherent(size, addr) ((void)0)
# define __dma_sync(addr, size, rw) ((void)0)
# define __dma_sync_page(pg, off, sz, rw) ((void)0)
# endif /* ! CONFIG_NOT_COHERENT_CACHE */
2008-07-05 05:05:45 +10:00
static inline unsigned long device_to_mask ( struct device * dev )
{
if ( dev - > dma_mask & & * dev - > dma_mask )
return * dev - > dma_mask ;
/* Assume devices without mask can take 32 bit addresses */
return 0xfffffffful ;
}
powerpc: Merge 32 and 64-bit dma code
We essentially adopt the 64-bit dma code, with some changes to support
32-bit systems, including HIGHMEM. dma functions on 32-bit are now
invoked via accessor functions which call the correct op for a device based
on archdata dma_ops. If there is no archdata dma_ops, this defaults
to dma_direct_ops.
In addition, the dma_map/unmap_page functions are added to dma_ops
because we can't just fall back on map/unmap_single when HIGHMEM is
enabled. In the case of dma_direct_*, we stop using map/unmap_single
and just use the page version - this saves a lot of ugly
ifdeffing. We leave map/unmap_single in the dma_ops definition,
though, because they are needed by the iommu code, which does not
implement map/unmap_page. Ideally, going forward, we will completely
eliminate map/unmap_single and just have map/unmap_page, if it's
workable for 64-bit.
Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-09-12 10:34:46 +00:00
/*
* Available generic sets of operations
*/
# ifdef CONFIG_PPC64
2009-08-04 19:08:25 +00:00
extern struct dma_map_ops dma_iommu_ops ;
powerpc: Merge 32 and 64-bit dma code
We essentially adopt the 64-bit dma code, with some changes to support
32-bit systems, including HIGHMEM. dma functions on 32-bit are now
invoked via accessor functions which call the correct op for a device based
on archdata dma_ops. If there is no archdata dma_ops, this defaults
to dma_direct_ops.
In addition, the dma_map/unmap_page functions are added to dma_ops
because we can't just fall back on map/unmap_single when HIGHMEM is
enabled. In the case of dma_direct_*, we stop using map/unmap_single
and just use the page version - this saves a lot of ugly
ifdeffing. We leave map/unmap_single in the dma_ops definition,
though, because they are needed by the iommu code, which does not
implement map/unmap_page. Ideally, going forward, we will completely
eliminate map/unmap_single and just have map/unmap_page, if it's
workable for 64-bit.
Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-09-12 10:34:46 +00:00
# endif
2009-08-04 19:08:25 +00:00
extern struct dma_map_ops dma_direct_ops ;
powerpc: Merge 32 and 64-bit dma code
We essentially adopt the 64-bit dma code, with some changes to support
32-bit systems, including HIGHMEM. dma functions on 32-bit are now
invoked via accessor functions which call the correct op for a device based
on archdata dma_ops. If there is no archdata dma_ops, this defaults
to dma_direct_ops.
In addition, the dma_map/unmap_page functions are added to dma_ops
because we can't just fall back on map/unmap_single when HIGHMEM is
enabled. In the case of dma_direct_*, we stop using map/unmap_single
and just use the page version - this saves a lot of ugly
ifdeffing. We leave map/unmap_single in the dma_ops definition,
though, because they are needed by the iommu code, which does not
implement map/unmap_page. Ideally, going forward, we will completely
eliminate map/unmap_single and just have map/unmap_page, if it's
workable for 64-bit.
Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-09-12 10:34:46 +00:00
2009-08-04 19:08:25 +00:00
static inline struct dma_map_ops * get_dma_ops ( struct device * dev )
2007-10-16 14:54:33 -05:00
{
/* We don't handle the NULL dev case for ISA for now. We could
* do it via an out of line call but it is not needed for now . The
* only ISA DMA device we support is the floppy and we have a hack
* in the floppy driver directly to get a device for us .
*/
2009-03-19 03:40:52 +00:00
if ( unlikely ( dev = = NULL ) )
2007-10-16 14:54:33 -05:00
return NULL ;
powerpc: Merge 32 and 64-bit dma code
We essentially adopt the 64-bit dma code, with some changes to support
32-bit systems, including HIGHMEM. dma functions on 32-bit are now
invoked via accessor functions which call the correct op for a device based
on archdata dma_ops. If there is no archdata dma_ops, this defaults
to dma_direct_ops.
In addition, the dma_map/unmap_page functions are added to dma_ops
because we can't just fall back on map/unmap_single when HIGHMEM is
enabled. In the case of dma_direct_*, we stop using map/unmap_single
and just use the page version - this saves a lot of ugly
ifdeffing. We leave map/unmap_single in the dma_ops definition,
though, because they are needed by the iommu code, which does not
implement map/unmap_page. Ideally, going forward, we will completely
eliminate map/unmap_single and just have map/unmap_page, if it's
workable for 64-bit.
Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-09-12 10:34:46 +00:00
2007-10-16 14:54:33 -05:00
return dev - > archdata . dma_ops ;
2008-01-30 01:13:58 +11:00
}
2009-08-04 19:08:25 +00:00
static inline void set_dma_ops ( struct device * dev , struct dma_map_ops * ops )
2008-01-30 01:13:58 +11:00
{
dev - > archdata . dma_ops = ops ;
2007-10-16 14:54:33 -05:00
}
2009-09-21 08:26:34 +00:00
/*
* get_dma_offset ( )
*
* Get the dma offset on configurations where the dma address can be determined
* from the physical address by looking at a simple offset . Direct dma and
* swiotlb use this function , but it is typically not used by implementations
* with an iommu .
*/
2009-09-21 08:26:35 +00:00
static inline dma_addr_t get_dma_offset ( struct device * dev )
2009-09-21 08:26:34 +00:00
{
if ( dev )
2015-06-24 15:25:22 +10:00
return dev - > archdata . dma_offset ;
2009-09-21 08:26:34 +00:00
return PCI_DRAM_OFFSET ;
}
2009-09-21 08:26:35 +00:00
static inline void set_dma_offset ( struct device * dev , dma_addr_t off )
{
if ( dev )
2015-06-24 15:25:22 +10:00
dev - > archdata . dma_offset = off ;
2009-09-21 08:26:35 +00:00
}
2009-08-04 19:08:26 +00:00
/* this will be removed soon */
# define flush_write_buffers()
2015-09-09 15:39:53 -07:00
# define HAVE_ARCH_DMA_SET_MASK 1
extern int dma_set_mask ( struct device * dev , u64 dma_mask ) ;
2014-02-11 11:32:38 +11:00
extern int __dma_set_mask ( struct device * dev , u64 dma_mask ) ;
2014-09-30 12:39:10 +10:00
extern u64 __dma_get_required_mask ( struct device * dev ) ;
2007-10-16 14:54:33 -05:00
2009-07-10 10:04:57 +09:00
static inline bool dma_capable ( struct device * dev , dma_addr_t addr , size_t size )
{
2009-08-04 19:08:22 +00:00
# ifdef CONFIG_SWIOTLB
struct dev_archdata * sd = & dev - > archdata ;
2009-07-10 10:04:57 +09:00
2009-08-04 19:08:22 +00:00
if ( sd - > max_direct_dma_addr & & addr + size > sd - > max_direct_dma_addr )
2015-03-30 16:46:04 -07:00
return false ;
2009-08-04 19:08:22 +00:00
# endif
2009-07-10 10:04:57 +09:00
if ( ! dev - > dma_mask )
2015-03-30 16:46:04 -07:00
return false ;
2009-07-10 10:04:57 +09:00
2009-12-15 16:47:43 -08:00
return addr + size - 1 < = * dev - > dma_mask ;
2009-07-10 10:04:57 +09:00
}
2009-07-10 10:05:01 +09:00
static inline dma_addr_t phys_to_dma ( struct device * dev , phys_addr_t paddr )
{
2009-09-21 08:26:34 +00:00
return paddr + get_dma_offset ( dev ) ;
2009-07-10 10:05:01 +09:00
}
static inline phys_addr_t dma_to_phys ( struct device * dev , dma_addr_t daddr )
{
2009-09-21 08:26:34 +00:00
return daddr - get_dma_offset ( dev ) ;
2009-07-10 10:05:01 +09:00
}
2011-03-24 20:50:06 +00:00
# define ARCH_HAS_DMA_MMAP_COHERENT
2006-12-06 20:38:56 -08:00
static inline void dma_cache_sync ( struct device * dev , void * vaddr , size_t size ,
2005-11-19 01:40:46 +11:00
enum dma_data_direction direction )
2005-04-16 15:20:36 -07:00
{
2005-11-19 01:40:46 +11:00
BUG_ON ( direction = = DMA_NONE ) ;
2005-04-16 15:20:36 -07:00
__dma_sync ( vaddr , size , ( int ) direction ) ;
}
2005-12-16 22:43:46 +01:00
# endif /* __KERNEL__ */
2005-11-19 01:40:46 +11:00
# endif /* _ASM_DMA_MAPPING_H */