aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorInki Dae <inki.dae@samsung.com>2012-10-19 04:37:35 -0400
committerInki Dae <inki.dae@samsung.com>2012-12-04 00:45:53 -0500
commit1055b39facd1bf8f84031a07385f84b46a20540f (patch)
treed139201e9880349f39f6435d6cc24cafdbea7a3c /drivers
parentbcc5cd1c5fad9b4471aafff0d74d9d0fcde1c27d (diff)
drm/exynos: add iommu support for hdmi driver
Changelog v2: move iommu support feature to mixer side. And below is Prathyush's comment. According to the new IOMMU framework for exynos sysmmus, the owner of the sysmmu-tv is mixer (which is the actual device that does DMA) and not hdmi. The mmu-master in sysmmu-tv node is set as below in exynos5250.dtsi sysmmu-tv { - mmu-master = <&mixer>; }; Changelog v1: The iommu will be enabled when hdmi sub driver is probed and will be disabled when removed. Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c15
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h1
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c23
4 files changed, 40 insertions, 1 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index c3b9e2b45185..2d11e70b601a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -346,9 +346,23 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
346 ctx->hdmi_ctx->drm_dev = drm_dev; 346 ctx->hdmi_ctx->drm_dev = drm_dev;
347 ctx->mixer_ctx->drm_dev = drm_dev; 347 ctx->mixer_ctx->drm_dev = drm_dev;
348 348
349 if (mixer_ops->iommu_on)
350 mixer_ops->iommu_on(ctx->mixer_ctx->ctx, true);
351
349 return 0; 352 return 0;
350} 353}
351 354
355static void hdmi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
356{
357 struct drm_hdmi_context *ctx;
358 struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
359
360 ctx = get_ctx_from_subdrv(subdrv);
361
362 if (mixer_ops->iommu_on)
363 mixer_ops->iommu_on(ctx->mixer_ctx->ctx, false);
364}
365
352static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) 366static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
353{ 367{
354 struct device *dev = &pdev->dev; 368 struct device *dev = &pdev->dev;
@@ -368,6 +382,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
368 subdrv->dev = dev; 382 subdrv->dev = dev;
369 subdrv->manager = &hdmi_manager; 383 subdrv->manager = &hdmi_manager;
370 subdrv->probe = hdmi_subdrv_probe; 384 subdrv->probe = hdmi_subdrv_probe;
385 subdrv->remove = hdmi_subdrv_remove;
371 386
372 platform_set_drvdata(pdev, subdrv); 387 platform_set_drvdata(pdev, subdrv);
373 388
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 2da5ffd3a059..54b522353e48 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -62,6 +62,7 @@ struct exynos_hdmi_ops {
62 62
63struct exynos_mixer_ops { 63struct exynos_mixer_ops {
64 /* manager */ 64 /* manager */
65 int (*iommu_on)(void *ctx, bool enable);
65 int (*enable_vblank)(void *ctx, int pipe); 66 int (*enable_vblank)(void *ctx, int pipe);
66 void (*disable_vblank)(void *ctx); 67 void (*disable_vblank)(void *ctx);
67 void (*dpms)(void *ctx, int mode); 68 void (*dpms)(void *ctx, int mode);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 2c115f8a62a3..c73f43874944 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -74,6 +74,7 @@ struct hdmi_context {
74 struct mutex hdmi_mutex; 74 struct mutex hdmi_mutex;
75 75
76 void __iomem *regs; 76 void __iomem *regs;
77 void *parent_ctx;
77 int external_irq; 78 int external_irq;
78 int internal_irq; 79 int internal_irq;
79 80
@@ -84,7 +85,6 @@ struct hdmi_context {
84 int cur_conf; 85 int cur_conf;
85 86
86 struct hdmi_resources res; 87 struct hdmi_resources res;
87 void *parent_ctx;
88 88
89 int hpd_gpio; 89 int hpd_gpio;
90 90
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 0d3ed282376c..50100cfddf4e 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -36,6 +36,7 @@
36 36
37#include "exynos_drm_drv.h" 37#include "exynos_drm_drv.h"
38#include "exynos_drm_hdmi.h" 38#include "exynos_drm_hdmi.h"
39#include "exynos_drm_iommu.h"
39 40
40#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) 41#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
41 42
@@ -80,6 +81,7 @@ enum mixer_version_id {
80 81
81struct mixer_context { 82struct mixer_context {
82 struct device *dev; 83 struct device *dev;
84 struct drm_device *drm_dev;
83 int pipe; 85 int pipe;
84 bool interlace; 86 bool interlace;
85 bool powered; 87 bool powered;
@@ -90,6 +92,7 @@ struct mixer_context {
90 struct mixer_resources mixer_res; 92 struct mixer_resources mixer_res;
91 struct hdmi_win_data win_data[MIXER_WIN_NR]; 93 struct hdmi_win_data win_data[MIXER_WIN_NR];
92 enum mixer_version_id mxr_ver; 94 enum mixer_version_id mxr_ver;
95 void *parent_ctx;
93}; 96};
94 97
95struct mixer_drv_data { 98struct mixer_drv_data {
@@ -665,6 +668,24 @@ static void mixer_win_reset(struct mixer_context *ctx)
665 spin_unlock_irqrestore(&res->reg_slock, flags); 668 spin_unlock_irqrestore(&res->reg_slock, flags);
666} 669}
667 670
671static int mixer_iommu_on(void *ctx, bool enable)
672{
673 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
674 struct mixer_context *mdata = ctx;
675 struct drm_device *drm_dev;
676
677 drm_hdmi_ctx = mdata->parent_ctx;
678 drm_dev = drm_hdmi_ctx->drm_dev;
679
680 if (is_drm_iommu_supported(drm_dev)) {
681 if (enable)
682 return drm_iommu_attach_device(drm_dev, mdata->dev);
683
684 drm_iommu_detach_device(drm_dev, mdata->dev);
685 }
686 return 0;
687}
688
668static void mixer_poweron(struct mixer_context *ctx) 689static void mixer_poweron(struct mixer_context *ctx)
669{ 690{
670 struct mixer_resources *res = &ctx->mixer_res; 691 struct mixer_resources *res = &ctx->mixer_res;
@@ -866,6 +887,7 @@ static void mixer_win_disable(void *ctx, int win)
866 887
867static struct exynos_mixer_ops mixer_ops = { 888static struct exynos_mixer_ops mixer_ops = {
868 /* manager */ 889 /* manager */
890 .iommu_on = mixer_iommu_on,
869 .enable_vblank = mixer_enable_vblank, 891 .enable_vblank = mixer_enable_vblank,
870 .disable_vblank = mixer_disable_vblank, 892 .disable_vblank = mixer_disable_vblank,
871 .dpms = mixer_dpms, 893 .dpms = mixer_dpms,
@@ -1140,6 +1162,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
1140 } 1162 }
1141 1163
1142 ctx->dev = &pdev->dev; 1164 ctx->dev = &pdev->dev;
1165 ctx->parent_ctx = (void *)drm_hdmi_ctx;
1143 drm_hdmi_ctx->ctx = (void *)ctx; 1166 drm_hdmi_ctx->ctx = (void *)ctx;
1144 ctx->vp_enabled = drv->is_vp_enabled; 1167 ctx->vp_enabled = drv->is_vp_enabled;
1145 ctx->mxr_ver = drv->version; 1168 ctx->mxr_ver = drv->version;