2012-10-20 07:53:42 -07:00
/* exynos_drm_iommu.h
*
* Copyright ( c ) 2012 Samsung Electronics Co . , Ltd .
* Authoer : Inki Dae < inki . dae @ samsung . com >
*
2012-12-18 02:30:17 +09:00
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
2012-10-20 07:53:42 -07:00
*/
# ifndef _EXYNOS_DRM_IOMMU_H_
# define _EXYNOS_DRM_IOMMU_H_
# define EXYNOS_DEV_ADDR_START 0x20000000
# define EXYNOS_DEV_ADDR_SIZE 0x40000000
# ifdef CONFIG_DRM_EXYNOS_IOMMU
2016-06-17 09:54:26 +02:00
# if defined(CONFIG_ARM_DMA_USE_IOMMU)
# include <asm/dma-iommu.h>
static inline int __exynos_iommu_create_mapping ( struct exynos_drm_private * priv ,
unsigned long start , unsigned long size )
{
priv - > mapping = arm_iommu_create_mapping ( & platform_bus_type , start ,
size ) ;
return IS_ERR ( priv - > mapping ) ;
}
static inline void
__exynos_iommu_release_mapping ( struct exynos_drm_private * priv )
{
arm_iommu_release_mapping ( priv - > mapping ) ;
}
static inline int __exynos_iommu_attach ( struct exynos_drm_private * priv ,
struct device * dev )
{
if ( dev - > archdata . mapping )
arm_iommu_detach_device ( dev ) ;
return arm_iommu_attach_device ( dev , priv - > mapping ) ;
}
static inline void __exynos_iommu_detach ( struct exynos_drm_private * priv ,
struct device * dev )
{
arm_iommu_detach_device ( dev ) ;
}
2016-06-17 09:54:27 +02:00
# elif defined(CONFIG_IOMMU_DMA)
# include <linux/dma-iommu.h>
static inline int __exynos_iommu_create_mapping ( struct exynos_drm_private * priv ,
unsigned long start , unsigned long size )
{
struct iommu_domain * domain ;
int ret ;
domain = iommu_domain_alloc ( priv - > dma_dev - > bus ) ;
if ( ! domain )
return - ENOMEM ;
ret = iommu_get_dma_cookie ( domain ) ;
if ( ret )
goto free_domain ;
2016-09-12 17:14:00 +01:00
ret = iommu_dma_init_domain ( domain , start , size , NULL ) ;
2016-06-17 09:54:27 +02:00
if ( ret )
goto put_cookie ;
priv - > mapping = domain ;
return 0 ;
put_cookie :
iommu_put_dma_cookie ( domain ) ;
free_domain :
iommu_domain_free ( domain ) ;
return ret ;
}
static inline void __exynos_iommu_release_mapping ( struct exynos_drm_private * priv )
{
struct iommu_domain * domain = priv - > mapping ;
iommu_put_dma_cookie ( domain ) ;
iommu_domain_free ( domain ) ;
priv - > mapping = NULL ;
}
static inline int __exynos_iommu_attach ( struct exynos_drm_private * priv ,
struct device * dev )
{
struct iommu_domain * domain = priv - > mapping ;
return iommu_attach_device ( domain , dev ) ;
}
static inline void __exynos_iommu_detach ( struct exynos_drm_private * priv ,
struct device * dev )
{
struct iommu_domain * domain = priv - > mapping ;
iommu_detach_device ( domain , dev ) ;
}
2016-06-17 09:54:26 +02:00
# else
# error Unsupported architecture and IOMMU / DMA-mapping glue code
# endif
2012-10-20 07:53:42 -07:00
int drm_create_iommu_mapping ( struct drm_device * drm_dev ) ;
void drm_release_iommu_mapping ( struct drm_device * drm_dev ) ;
int drm_iommu_attach_device ( struct drm_device * drm_dev ,
struct device * subdrv_dev ) ;
void drm_iommu_detach_device ( struct drm_device * dev_dev ,
struct device * subdrv_dev ) ;
static inline bool is_drm_iommu_supported ( struct drm_device * drm_dev )
{
2016-02-29 17:50:53 +09:00
struct exynos_drm_private * priv = drm_dev - > dev_private ;
2012-10-20 07:53:42 -07:00
2016-02-29 17:50:53 +09:00
return priv - > mapping ? true : false ;
2012-10-20 07:53:42 -07:00
}
# else
static inline int drm_create_iommu_mapping ( struct drm_device * drm_dev )
{
return 0 ;
}
static inline void drm_release_iommu_mapping ( struct drm_device * drm_dev )
{
}
static inline int drm_iommu_attach_device ( struct drm_device * drm_dev ,
struct device * subdrv_dev )
{
return 0 ;
}
static inline void drm_iommu_detach_device ( struct drm_device * drm_dev ,
struct device * subdrv_dev )
{
}
static inline bool is_drm_iommu_supported ( struct drm_device * drm_dev )
{
return false ;
}
# endif
# endif