2005-04-16 15:20:36 -07:00
/*
* Copyright ( c ) 2004 Hewlett - Packard Development Company , L . P .
* Contributed by David Mosberger - Tang < davidm @ hpl . hp . com >
*
* This is a pseudo I / O MMU which dispatches to the hardware I / O MMU
* whenever possible . We assume that the hardware I / O MMU requires
* full 32 - bit addressability , as is the case , e . g . , for HP zx1 - based
* systems ( there , the I / O MMU window is mapped at 3 - 4 GB ) . If a
* device doesn ' t provide full 32 - bit addressability , we fall back on
* the sw I / O TLB . This is good enough to let us support broken
* hardware such as soundcards which have a DMA engine that can
* address only 28 bits .
*/
# include <linux/device.h>
2009-01-05 23:36:08 +09:00
# include <linux/dma-mapping.h>
2008-10-29 14:17:59 -07:00
# include <linux/swiotlb.h>
2011-07-31 18:33:21 -04:00
# include <linux/export.h>
2005-04-16 15:20:36 -07:00
# include <asm/machvec.h>
2009-01-05 23:59:02 +09:00
extern struct dma_map_ops sba_dma_ops , swiotlb_dma_ops ;
2009-01-05 23:36:17 +09:00
2005-04-16 15:20:36 -07:00
/* swiotlb declarations & definitions: */
2005-09-06 11:20:49 -06:00
extern int swiotlb_late_init_with_default_size ( size_t size ) ;
2005-04-16 15:20:36 -07:00
/*
* Note : we need to make the determination of whether or not to use
* the sw I / O TLB based purely on the device structure . Anything else
* would be unreliable or would be too intrusive .
*/
2009-01-05 23:36:17 +09:00
static inline int use_swiotlb ( struct device * dev )
2005-04-16 15:20:36 -07:00
{
2009-01-05 23:36:17 +09:00
return dev & & dev - > dma_mask & &
2009-01-05 23:59:02 +09:00
! sba_dma_ops . dma_supported ( dev , * dev - > dma_mask ) ;
2005-04-16 15:20:36 -07:00
}
2009-01-05 23:59:02 +09:00
struct dma_map_ops * hwsw_dma_get_ops ( struct device * dev )
2009-01-05 23:36:17 +09:00
{
if ( use_swiotlb ( dev ) )
return & swiotlb_dma_ops ;
return & sba_dma_ops ;
}
EXPORT_SYMBOL ( hwsw_dma_get_ops ) ;
2009-01-05 23:36:12 +09:00
2007-05-10 11:57:58 -07:00
void __init
2005-04-16 15:20:36 -07:00
hwsw_init ( void )
{
/* default to a smallish 2MB sw I/O TLB */
2005-09-06 11:20:49 -06:00
if ( swiotlb_late_init_with_default_size ( 2 * ( 1 < < 20 ) ) ! = 0 ) {
# ifdef CONFIG_IA64_GENERIC
/* Better to have normal DMA than panic */
printk ( KERN_WARNING " %s: Failed to initialize software I/O TLB, "
2008-03-04 15:15:00 -08:00
" reverting to hpzx1 platform vector \n " , __func__ ) ;
2005-09-06 11:20:49 -06:00
machvec_init ( " hpzx1 " ) ;
# else
panic ( " Unable to initialize software I/O TLB services " ) ;
# endif
}
2005-04-16 15:20:36 -07:00
}