diff options
| author | Marek Szyprowski <m.szyprowski@samsung.com> | 2016-06-17 03:54:27 -0400 |
|---|---|---|
| committer | Inki Dae <daeinki@gmail.com> | 2016-07-13 10:06:07 -0400 |
| commit | 197adf0b7e419247a6e54d05d0d334e07e9e4c33 (patch) | |
| tree | 6bbca2dafc6d103d050c386a6dd6f900ea1a6699 | |
| parent | 17879a4100f15156b415f37190576f30a5cfae00 (diff) | |
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>
| -rw-r--r-- | drivers/gpu/drm/exynos/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_iommu.h | 55 |
3 files changed, 57 insertions, 7 deletions
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index d814b3048ee5..343813a5fbc8 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
| @@ -15,7 +15,7 @@ if DRM_EXYNOS | |||
| 15 | 15 | ||
| 16 | config DRM_EXYNOS_IOMMU | 16 | config DRM_EXYNOS_IOMMU |
| 17 | bool | 17 | bool |
| 18 | depends on EXYNOS_IOMMU && ARM_DMA_USE_IOMMU | 18 | depends on EXYNOS_IOMMU |
| 19 | default y | 19 | default y |
| 20 | 20 | ||
| 21 | comment "CRTCs" | 21 | comment "CRTCs" |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 13d28d4229e2..877d2efa28e2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -159,12 +159,7 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
| 159 | DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n", | 159 | DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n", |
| 160 | dev_name(private->dma_dev)); | 160 | dev_name(private->dma_dev)); |
| 161 | 161 | ||
| 162 | /* | 162 | /* create common IOMMU mapping for all devices attached to Exynos DRM */ |
| 163 | * create mapping to manage iommu table and set a pointer to iommu | ||
| 164 | * mapping structure to iommu_mapping of private data. | ||
| 165 | * also this iommu_mapping can be used to check if iommu is supported | ||
| 166 | * or not. | ||
| 167 | */ | ||
| 168 | ret = drm_create_iommu_mapping(dev); | 163 | ret = drm_create_iommu_mapping(dev); |
| 169 | if (ret < 0) { | 164 | if (ret < 0) { |
| 170 | DRM_ERROR("failed to create iommu mapping.\n"); | 165 | DRM_ERROR("failed to create iommu mapping.\n"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/drivers/gpu/drm/exynos/exynos_drm_iommu.h index 22e1df2ac62e..c8de4913fdbe 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h +++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h | |||
| @@ -49,6 +49,61 @@ static inline void __exynos_iommu_detach(struct exynos_drm_private *priv, | |||
| 49 | arm_iommu_detach_device(dev); | 49 | arm_iommu_detach_device(dev); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | #elif defined(CONFIG_IOMMU_DMA) | ||
| 53 | #include <linux/dma-iommu.h> | ||
| 54 | |||
| 55 | static inline int __exynos_iommu_create_mapping(struct exynos_drm_private *priv, | ||
| 56 | unsigned long start, unsigned long size) | ||
| 57 | { | ||
| 58 | struct iommu_domain *domain; | ||
| 59 | int ret; | ||
| 60 | |||
| 61 | domain = iommu_domain_alloc(priv->dma_dev->bus); | ||
| 62 | if (!domain) | ||
| 63 | return -ENOMEM; | ||
| 64 | |||
| 65 | ret = iommu_get_dma_cookie(domain); | ||
| 66 | if (ret) | ||
| 67 | goto free_domain; | ||
| 68 | |||
| 69 | ret = iommu_dma_init_domain(domain, start, size); | ||
| 70 | if (ret) | ||
| 71 | goto put_cookie; | ||
| 72 | |||
| 73 | priv->mapping = domain; | ||
| 74 | return 0; | ||
| 75 | |||
| 76 | put_cookie: | ||
| 77 | iommu_put_dma_cookie(domain); | ||
| 78 | free_domain: | ||
| 79 | iommu_domain_free(domain); | ||
| 80 | return ret; | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void __exynos_iommu_release_mapping(struct exynos_drm_private *priv) | ||
| 84 | { | ||
| 85 | struct iommu_domain *domain = priv->mapping; | ||
| 86 | |||
| 87 | iommu_put_dma_cookie(domain); | ||
| 88 | iommu_domain_free(domain); | ||
| 89 | priv->mapping = NULL; | ||
| 90 | } | ||
| 91 | |||
| 92 | static inline int __exynos_iommu_attach(struct exynos_drm_private *priv, | ||
| 93 | struct device *dev) | ||
| 94 | { | ||
| 95 | struct iommu_domain *domain = priv->mapping; | ||
| 96 | |||
| 97 | return iommu_attach_device(domain, dev); | ||
| 98 | } | ||
| 99 | |||
| 100 | static inline void __exynos_iommu_detach(struct exynos_drm_private *priv, | ||
| 101 | struct device *dev) | ||
| 102 | { | ||
| 103 | struct iommu_domain *domain = priv->mapping; | ||
| 104 | |||
| 105 | iommu_detach_device(domain, dev); | ||
| 106 | } | ||
| 52 | #else | 107 | #else |
| 53 | #error Unsupported architecture and IOMMU/DMA-mapping glue code | 108 | #error Unsupported architecture and IOMMU/DMA-mapping glue code |
| 54 | #endif | 109 | #endif |
