summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorEunchul Kim <chulspro.kim@samsung.com>2012-12-14 17:58:54 +0900
committerInki Dae <daeinki@gmail.com>2012-12-15 02:29:08 +0900
commitc12e2617b25535014a766a0bc3e05134ef817b82 (patch)
tree0ced95bb0ce611706ee9706ec2a5940703164aee /drivers/gpu/drm
parentcb471f14b5eebfed22bb9f2d0f06601f171c574a (diff)
downloadlinux-3.10-c12e2617b25535014a766a0bc3e05134ef817b82.tar.gz
linux-3.10-c12e2617b25535014a766a0bc3e05134ef817b82.tar.bz2
linux-3.10-c12e2617b25535014a766a0bc3e05134ef817b82.zip
drm/exynos: add iommu support for ipp
This patch adds iommu support for IPP subsystem framework. For this, it adds subdrv_probe/remove callback to enable or disable ipp iommu. We can get or put device address to a gem handle from user through exynos_drm_gem_get/put_dma_addr(). Signed-off-by: Eunchul Kim <chulspro.kim@samsung.com> Signed-off-by: Jinyoung Jeon <jy0.jeon@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index c640935ab7d..49eebe948ed 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -24,6 +24,7 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_gem.h"
#include "exynos_drm_ipp.h"
+#include "exynos_drm_iommu.h"
/*
* IPP is stand for Image Post Processing and
@@ -1771,10 +1772,24 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
ippdrv->event_workq = ctx->event_workq;
ippdrv->sched_event = ipp_sched_event;
INIT_LIST_HEAD(&ippdrv->cmd_list);
+
+ if (is_drm_iommu_supported(drm_dev)) {
+ ret = drm_iommu_attach_device(drm_dev, ippdrv->dev);
+ if (ret) {
+ DRM_ERROR("failed to activate iommu\n");
+ goto err_iommu;
+ }
+ }
}
return 0;
+err_iommu:
+ /* get ipp driver entry */
+ list_for_each_entry_reverse(ippdrv, &exynos_drm_ippdrv_list, drv_list)
+ if (is_drm_iommu_supported(drm_dev))
+ drm_iommu_detach_device(drm_dev, ippdrv->dev);
+
err_idr:
idr_remove_all(&ctx->ipp_idr);
idr_remove_all(&ctx->prop_idr);
@@ -1791,6 +1806,9 @@ static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
/* get ipp driver entry */
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
+ if (is_drm_iommu_supported(drm_dev))
+ drm_iommu_detach_device(drm_dev, ippdrv->dev);
+
ippdrv->drm_dev = NULL;
exynos_drm_ippdrv_unregister(ippdrv);
}