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
# define DMA_ERROR_CODE (~(dma_addr_t)0x0)
2009-05-14 12:42:28 +00:00
/* Some dma direct funcs must be visible for use in other dma_ops */
extern void * dma_direct_alloc_coherent ( struct device * dev , size_t size ,
dma_addr_t * dma_handle , gfp_t flag ) ;
extern void dma_direct_free_coherent ( struct device * dev , size_t size ,
void * vaddr , dma_addr_t dma_handle ) ;
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 ) ;
# 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 )
2009-09-21 08:26:35 +00:00
return dev - > archdata . dma_data . 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 )
dev - > archdata . dma_data . dma_offset = off ;
}
2009-08-04 19:08:26 +00:00
/* this will be removed soon */
# define flush_write_buffers()
# include <asm-generic/dma-mapping-common.h>
2007-10-16 14:54:33 -05:00
static inline int dma_supported ( struct device * dev , u64 mask )
{
2009-08-04 19:08:25 +00:00
struct dma_map_ops * dma_ops = get_dma_ops ( dev ) ;
2007-10-16 14:54:33 -05:00
if ( unlikely ( dma_ops = = NULL ) )
return 0 ;
if ( dma_ops - > dma_supported = = NULL )
return 1 ;
return dma_ops - > dma_supported ( dev , mask ) ;
}
2007-12-17 17:35:53 +11:00
/* We have our own implementation of pci_set_dma_mask() */
# define HAVE_ARCH_PCI_SET_DMA_MASK
2007-10-16 14:54:33 -05:00
static inline int dma_set_mask ( struct device * dev , u64 dma_mask )
{
2009-08-04 19:08:25 +00:00
struct dma_map_ops * dma_ops = get_dma_ops ( dev ) ;
2007-10-16 14:54:33 -05:00
if ( unlikely ( dma_ops = = NULL ) )
return - EIO ;
if ( dma_ops - > set_dma_mask ! = NULL )
return dma_ops - > set_dma_mask ( dev , dma_mask ) ;
if ( ! dev - > dma_mask | | ! dma_supported ( dev , dma_mask ) )
return - EIO ;
* dev - > dma_mask = dma_mask ;
return 0 ;
}
static inline void * dma_alloc_coherent ( struct device * dev , size_t size ,
dma_addr_t * dma_handle , gfp_t flag )
{
2009-08-04 19:08:25 +00:00
struct dma_map_ops * dma_ops = get_dma_ops ( dev ) ;
2009-08-04 19:08:28 +00:00
void * cpu_addr ;
2007-10-16 14:54:33 -05:00
BUG_ON ( ! dma_ops ) ;
2009-08-04 19:08:28 +00:00
cpu_addr = dma_ops - > alloc_coherent ( dev , size , dma_handle , flag ) ;
debug_dma_alloc_coherent ( dev , size , * dma_handle , cpu_addr ) ;
return cpu_addr ;
2007-10-16 14:54:33 -05:00
}
static inline void dma_free_coherent ( struct device * dev , size_t size ,
void * cpu_addr , dma_addr_t dma_handle )
{
2009-08-04 19:08:25 +00:00
struct dma_map_ops * dma_ops = get_dma_ops ( dev ) ;
2007-10-16 14:54:33 -05:00
BUG_ON ( ! dma_ops ) ;
2009-08-04 19:08:28 +00:00
debug_dma_free_coherent ( dev , size , cpu_addr , dma_handle ) ;
2007-10-16 14:54:33 -05:00
dma_ops - > free_coherent ( dev , size , cpu_addr , dma_handle ) ;
}
2008-07-25 19:44:49 -07:00
static inline int dma_mapping_error ( struct device * dev , dma_addr_t dma_addr )
2005-11-19 01:40:46 +11:00
{
2009-08-04 19:08:27 +00:00
struct dma_map_ops * dma_ops = get_dma_ops ( dev ) ;
if ( dma_ops - > mapping_error )
return dma_ops - > mapping_error ( dev , dma_addr ) ;
2005-11-19 01:40:46 +11:00
# ifdef CONFIG_PPC64
return ( dma_addr = = DMA_ERROR_CODE ) ;
# else
return 0 ;
# endif
}
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 )
2009-07-10 10:04:57 +09:00
return 0 ;
2009-08-04 19:08:22 +00:00
# endif
2009-07-10 10:04:57 +09:00
if ( ! dev - > dma_mask )
return 0 ;
return addr + size < = * dev - > dma_mask ;
}
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
}
2005-04-16 15:20:36 -07:00
# define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
# define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
# ifdef CONFIG_NOT_COHERENT_CACHE
2006-12-06 20:38:54 -08:00
# define dma_is_consistent(d, h) (0)
2005-04-16 15:20:36 -07:00
# else
2006-12-06 20:38:54 -08:00
# define dma_is_consistent(d, h) (1)
2005-04-16 15:20:36 -07:00
# endif
static inline int dma_get_cache_alignment ( void )
{
2005-11-19 01:40:46 +11:00
# ifdef CONFIG_PPC64
/* no easy way to get cache size on all processors, so return
* the maximum possible , to be safe */
2006-01-08 01:01:28 -08:00
return ( 1 < < INTERNODE_CACHE_SHIFT ) ;
2005-11-19 01:40:46 +11:00
# else
2005-04-16 15:20:36 -07:00
/*
* Each processor family will define its own L1_CACHE_SHIFT ,
* L1_CACHE_BYTES wraps to this , so this is always safe .
*/
return L1_CACHE_BYTES ;
2005-11-19 01:40:46 +11:00
# endif
2005-04-16 15:20:36 -07:00
}
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 */