2005-04-16 15:20:36 -07:00
/*
2006-11-11 17:25:02 +11:00
* Copyright ( C ) 2006 Benjamin Herrenschmidt , IBM Corporation
2005-04-16 15:20:36 -07:00
*
2006-11-11 17:25:02 +11:00
* Provide default implementations of the DMA mapping callbacks for
2008-09-08 09:09:53 +00:00
* directly mapped busses .
2005-04-16 15:20:36 -07:00
*/
# include <linux/device.h>
# include <linux/dma-mapping.h>
# include <asm/bug.h>
2006-11-11 17:25:02 +11:00
# include <asm/abs_addr.h>
2005-04-16 15:20:36 -07:00
2006-11-11 17:25:02 +11:00
/*
* Generic direct DMA implementation
2006-11-11 17:25:14 +11:00
*
2008-01-21 16:42:48 +11:00
* This implementation supports a per - device offset that can be applied if
* the address at which memory is visible to devices is not 0. Platform code
* can set archdata . dma_data to an unsigned long holding the offset . By
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
* default the offset is PCI_DRAM_OFFSET .
2006-11-11 17:25:02 +11:00
*/
2006-07-13 16:32:52 +10:00
2008-01-21 16:42:43 +11:00
static unsigned long get_dma_direct_offset ( struct device * dev )
{
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
if ( dev )
return ( unsigned long ) dev - > archdata . dma_data ;
return PCI_DRAM_OFFSET ;
2008-01-21 16:42:43 +11:00
}
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
void * dma_direct_alloc_coherent ( struct device * dev , size_t size ,
dma_addr_t * dma_handle , gfp_t flag )
2006-11-11 17:25:02 +11:00
{
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
# ifdef CONFIG_NOT_COHERENT_CACHE
return __dma_alloc_coherent ( size , dma_handle , flag ) ;
# else
2006-11-11 17:25:16 +11:00
struct page * page ;
2006-11-11 17:25:02 +11:00
void * ret ;
2008-09-08 09:09:54 +00:00
int node = dev_to_node ( dev ) ;
2006-11-11 17:25:02 +11:00
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
/* ignore region specifiers */
flag & = ~ ( __GFP_HIGHMEM ) ;
2006-11-11 17:25:16 +11:00
page = alloc_pages_node ( node , flag , get_order ( size ) ) ;
if ( page = = NULL )
return NULL ;
ret = page_address ( page ) ;
memset ( ret , 0 , size ) ;
2008-01-21 16:42:43 +11:00
* dma_handle = virt_to_abs ( ret ) + get_dma_direct_offset ( dev ) ;
2006-11-11 17:25:16 +11:00
2006-11-11 17:25:02 +11:00
return ret ;
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
2005-04-16 15:20:36 -07:00
}
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
void dma_direct_free_coherent ( struct device * dev , size_t size ,
void * vaddr , dma_addr_t dma_handle )
2005-04-16 15:20:36 -07:00
{
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
# ifdef CONFIG_NOT_COHERENT_CACHE
__dma_free_coherent ( size , vaddr ) ;
# else
2006-11-11 17:25:02 +11:00
free_pages ( ( unsigned long ) vaddr , get_order ( size ) ) ;
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
2005-04-16 15:20:36 -07:00
}
2007-10-12 13:44:12 +02:00
static int dma_direct_map_sg ( struct device * dev , struct scatterlist * sgl ,
2008-07-05 05:05:42 +10:00
int nents , enum dma_data_direction direction ,
struct dma_attrs * attrs )
2005-04-16 15:20:36 -07:00
{
2007-10-12 13:44:12 +02:00
struct scatterlist * sg ;
2006-11-11 17:25:02 +11:00
int i ;
2005-04-16 15:20:36 -07:00
2007-10-12 13:44:12 +02:00
for_each_sg ( sgl , sg , nents , i ) {
2008-01-21 16:42:43 +11:00
sg - > dma_address = sg_phys ( sg ) + get_dma_direct_offset ( dev ) ;
2006-11-11 17:25:02 +11:00
sg - > dma_length = sg - > length ;
}
2006-07-13 16:32:52 +10:00
2006-11-11 17:25:02 +11:00
return nents ;
2005-04-16 15:20:36 -07:00
}
2006-11-11 17:25:02 +11:00
static void dma_direct_unmap_sg ( struct device * dev , struct scatterlist * sg ,
2008-07-05 05:05:42 +10:00
int nents , enum dma_data_direction direction ,
struct dma_attrs * attrs )
2005-04-16 15:20:36 -07:00
{
2006-11-11 17:25:02 +11:00
}
2006-07-13 16:32:52 +10:00
2006-11-11 17:25:02 +11:00
static int dma_direct_dma_supported ( struct device * dev , u64 mask )
{
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
# ifdef CONFIG_PPC64
2006-11-11 17:25:02 +11:00
/* Could be improved to check for memory though it better be
* done via some global so platforms can set the limit in case
* they have limited DMA windows
*/
return mask > = DMA_32BIT_MASK ;
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
# else
return 1 ;
# endif
}
static inline dma_addr_t dma_direct_map_page ( struct device * dev ,
struct page * page ,
unsigned long offset ,
size_t size ,
enum dma_data_direction dir ,
struct dma_attrs * attrs )
{
BUG_ON ( dir = = DMA_NONE ) ;
__dma_sync_page ( page , offset , size , dir ) ;
return page_to_phys ( page ) + offset + get_dma_direct_offset ( dev ) ;
}
static inline void dma_direct_unmap_page ( struct device * dev ,
dma_addr_t dma_address ,
size_t size ,
enum dma_data_direction direction ,
struct dma_attrs * attrs )
{
2005-04-16 15:20:36 -07:00
}
2006-11-11 17:25:02 +11:00
struct dma_mapping_ops dma_direct_ops = {
. alloc_coherent = dma_direct_alloc_coherent ,
. free_coherent = dma_direct_free_coherent ,
. map_sg = dma_direct_map_sg ,
. unmap_sg = dma_direct_unmap_sg ,
. dma_supported = dma_direct_dma_supported ,
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
. map_page = dma_direct_map_page ,
. unmap_page = dma_direct_unmap_page ,
2006-11-11 17:25:02 +11:00
} ;
EXPORT_SYMBOL ( dma_direct_ops ) ;