drm/exynos: iommu: add support for ARM64 specific code for IOMMU glue
This patch adds support for ARM 64bit architecture with IOMMU-DMA glue code, so Exynos DRM can be now used on Exynos 5433 with IOMMU enabled. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
17879a4100
commit
197adf0b7e
|
@ -15,7 +15,7 @@ if DRM_EXYNOS
|
||||||
|
|
||||||
config DRM_EXYNOS_IOMMU
|
config DRM_EXYNOS_IOMMU
|
||||||
bool
|
bool
|
||||||
depends on EXYNOS_IOMMU && ARM_DMA_USE_IOMMU
|
depends on EXYNOS_IOMMU
|
||||||
default y
|
default y
|
||||||
|
|
||||||
comment "CRTCs"
|
comment "CRTCs"
|
||||||
|
|
|
@ -159,12 +159,7 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
|
||||||
DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
|
DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
|
||||||
dev_name(private->dma_dev));
|
dev_name(private->dma_dev));
|
||||||
|
|
||||||
/*
|
/* create common IOMMU mapping for all devices attached to Exynos DRM */
|
||||||
* create mapping to manage iommu table and set a pointer to iommu
|
|
||||||
* mapping structure to iommu_mapping of private data.
|
|
||||||
* also this iommu_mapping can be used to check if iommu is supported
|
|
||||||
* or not.
|
|
||||||
*/
|
|
||||||
ret = drm_create_iommu_mapping(dev);
|
ret = drm_create_iommu_mapping(dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
DRM_ERROR("failed to create iommu mapping.\n");
|
DRM_ERROR("failed to create iommu mapping.\n");
|
||||||
|
|
|
@ -49,6 +49,61 @@ static inline void __exynos_iommu_detach(struct exynos_drm_private *priv,
|
||||||
arm_iommu_detach_device(dev);
|
arm_iommu_detach_device(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
ret = iommu_dma_init_domain(domain, start, size);
|
||||||
|
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);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture and IOMMU/DMA-mapping glue code
|
#error Unsupported architecture and IOMMU/DMA-mapping glue code
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue