diff mbox

drm/exynos: enable iommu for mixer and not hdmi

Message ID 1354516720-4807-1-git-send-email-prathyush.k@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Prathyush K Dec. 3, 2012, 6:38 a.m. UTC
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>;
};

This patch moves the iommu_on function from the hdmi context to the
mixer context.

And this patch is based on exynos-drm-next-iommu branch of
git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos

Signed-off-by: Prathyush K <prathyush.k@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c |    8 ++++----
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h |    2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c     |   24 ------------------------
 drivers/gpu/drm/exynos/exynos_mixer.c    |   23 +++++++++++++++++++++++
 4 files changed, 28 insertions(+), 29 deletions(-)

Comments

Inki Dae Dec. 4, 2012, 5:28 a.m. UTC | #1
2012/12/3 Prathyush K <prathyush.k@samsung.com>

> 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>;
> };
>
> This patch moves the iommu_on function from the hdmi context to the
> mixer context.
>


Right, that works fine as is but the iommu support should be moved to mixer
side anyway.
But this patch hasn't been merged to mainline so we are enough to leave
comment so that this can be fixed. Otherwise, unnecessary commits could be
applied to mainline.
So I will post patch v2 for hdmi iommu support.

Thanks,
Inki Dae


>
> And this patch is based on exynos-drm-next-iommu branch of
> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos
>
> Signed-off-by: Prathyush K <prathyush.k@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.c |    8 ++++----
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h |    2 +-
>  drivers/gpu/drm/exynos/exynos_hdmi.c     |   24 ------------------------
>  drivers/gpu/drm/exynos/exynos_mixer.c    |   23 +++++++++++++++++++++++
>  4 files changed, 28 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> index 997fb6e..8b771a3 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> @@ -368,8 +368,8 @@ static int hdmi_subdrv_probe(struct drm_device
> *drm_dev,
>         ctx->hdmi_ctx->drm_dev = drm_dev;
>         ctx->mixer_ctx->drm_dev = drm_dev;
>
> -       if (hdmi_ops->iommu_on)
> -               hdmi_ops->iommu_on(ctx->hdmi_ctx->ctx, true);
> +       if (mixer_ops->iommu_on)
> +               mixer_ops->iommu_on(ctx->mixer_ctx->ctx, true);
>
>         return 0;
>  }
> @@ -381,8 +381,8 @@ static void hdmi_subdrv_remove(struct drm_device
> *drm_dev, struct device *dev)
>
>         ctx = get_ctx_from_subdrv(subdrv);
>
> -       if (hdmi_ops->iommu_on)
> -               hdmi_ops->iommu_on(ctx->hdmi_ctx->ctx, false);
> +       if (mixer_ops->iommu_on)
> +               mixer_ops->iommu_on(ctx->mixer_ctx->ctx, false);
>  }
>
>  static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> index 5c033d1..54b5223 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> @@ -50,7 +50,6 @@ struct exynos_hdmi_ops {
>         int (*power_on)(void *ctx, int mode);
>
>         /* manager */
> -       int (*iommu_on)(void *ctx, bool enable);
>         void (*mode_fixup)(void *ctx, struct drm_connector *connector,
>                                 const struct drm_display_mode *mode,
>                                 struct drm_display_mode *adjusted_mode);
> @@ -63,6 +62,7 @@ struct exynos_hdmi_ops {
>
>  struct exynos_mixer_ops {
>         /* manager */
> +       int (*iommu_on)(void *ctx, bool enable);
>         int (*enable_vblank)(void *ctx, int pipe);
>         void (*disable_vblank)(void *ctx);
>         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 d1a1d71..7df1d85 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -40,7 +40,6 @@
>
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_hdmi.h"
> -#include "exynos_drm_iommu.h"
>
>  #include "exynos_hdmi.h"
>
> @@ -68,7 +67,6 @@ struct hdmi_resources {
>
>  struct hdmi_context {
>         struct device                   *dev;
> -       struct drm_device               *drm_dev;
>         bool                            hpd;
>         bool                            powered;
>         bool                            dvi_mode;
> @@ -85,7 +83,6 @@ struct hdmi_context {
>         int cur_conf;
>
>         struct hdmi_resources           res;
> -       void                            *parent_ctx;
>
>         int                             hpd_gpio;
>
> @@ -1947,25 +1944,6 @@ static void hdmi_conf_apply(struct hdmi_context
> *hdata)
>         hdmi_regs_dump(hdata, "start");
>  }
>
> -static int hdmi_iommu_on(void *ctx, bool enable)
> -{
> -       struct exynos_drm_hdmi_context *drm_hdmi_ctx;
> -       struct hdmi_context *hdata = ctx;
> -       struct drm_device *drm_dev;
> -
> -       drm_hdmi_ctx = hdata->parent_ctx;
> -       drm_dev = drm_hdmi_ctx->drm_dev;
> -
> -       if (is_drm_iommu_supported(drm_dev)) {
> -               if (enable)
> -                       return drm_iommu_attach_device(drm_dev,
> hdata->dev);
> -
> -               drm_iommu_detach_device(drm_dev, hdata->dev);
> -       }
> -
> -       return 0;
> -}
> -
>  static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
>                                 const struct drm_display_mode *mode,
>                                 struct drm_display_mode *adjusted_mode)
> @@ -2122,7 +2100,6 @@ static struct exynos_hdmi_ops hdmi_ops = {
>         .check_timing   = hdmi_check_timing,
>
>         /* manager */
> -       .iommu_on       = hdmi_iommu_on,
>         .mode_fixup     = hdmi_mode_fixup,
>         .mode_set       = hdmi_mode_set,
>         .get_max_resol  = hdmi_get_max_resol,
> @@ -2379,7 +2356,6 @@ static int __devinit hdmi_probe(struct
> platform_device *pdev)
>         mutex_init(&hdata->hdmi_mutex);
>
>         drm_hdmi_ctx->ctx = (void *)hdata;
> -       hdata->parent_ctx = (void *)drm_hdmi_ctx;
>
>         platform_set_drvdata(pdev, drm_hdmi_ctx);
>
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c
> b/drivers/gpu/drm/exynos/exynos_mixer.c
> index 614b2e9..574ed3f 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -36,6 +36,7 @@
>
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_hdmi.h"
> +#include "exynos_drm_iommu.h"
>
>  #define get_mixer_context(dev)
> platform_get_drvdata(to_platform_device(dev))
>
> @@ -80,6 +81,7 @@ enum mixer_version_id {
>
>  struct mixer_context {
>         struct device           *dev;
> +       struct drm_device       *drm_dev;
>         int                     pipe;
>         bool                    interlace;
>         bool                    powered;
> @@ -90,6 +92,7 @@ struct mixer_context {
>         struct mixer_resources  mixer_res;
>         struct hdmi_win_data    win_data[MIXER_WIN_NR];
>         enum mixer_version_id   mxr_ver;
> +       void                    *parent_ctx;
>  };
>
>  struct mixer_drv_data {
> @@ -665,6 +668,24 @@ static void mixer_win_reset(struct mixer_context *ctx)
>         spin_unlock_irqrestore(&res->reg_slock, flags);
>  }
>
> +static int mixer_iommu_on(void *ctx, bool enable)
> +{
> +       struct exynos_drm_hdmi_context *drm_hdmi_ctx;
> +       struct mixer_context *mdata = ctx;
> +       struct drm_device *drm_dev;
> +
> +       drm_hdmi_ctx = mdata->parent_ctx;
> +       drm_dev = drm_hdmi_ctx->drm_dev;
> +
> +       if (is_drm_iommu_supported(drm_dev)) {
> +               if (enable)
> +                       return drm_iommu_attach_device(drm_dev,
> mdata->dev);
> +
> +               drm_iommu_detach_device(drm_dev, mdata->dev);
> +       }
> +       return 0;
> +}
> +
>  static void mixer_poweron(struct mixer_context *ctx)
>  {
>         struct mixer_resources *res = &ctx->mixer_res;
> @@ -866,6 +887,7 @@ static void mixer_win_disable(void *ctx, int win)
>
>  static struct exynos_mixer_ops mixer_ops = {
>         /* manager */
> +       .iommu_on               = mixer_iommu_on,
>         .enable_vblank          = mixer_enable_vblank,
>         .disable_vblank         = mixer_disable_vblank,
>         .dpms                   = mixer_dpms,
> @@ -1149,6 +1171,7 @@ static int __devinit mixer_probe(struct
> platform_device *pdev)
>         }
>
>         ctx->dev = &pdev->dev;
> +       ctx->parent_ctx = (void *)drm_hdmi_ctx;
>         drm_hdmi_ctx->ctx = (void *)ctx;
>         ctx->vp_enabled = drv->is_vp_enabled;
>         ctx->mxr_ver = drv->version;
> --
> 1.7.0.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
Inki Dae Dec. 4, 2012, 6:03 a.m. UTC | #2
And Below is my comments and please send them as code cleanup. Actually,
your patch includes code cleanup also.

Thanks,
Inki Dae


2012/12/3 Prathyush K <prathyush.k@samsung.com>

> 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>;
> };
>
> This patch moves the iommu_on function from the hdmi context to the
> mixer context.
>
> And this patch is based on exynos-drm-next-iommu branch of
> git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos
>
> Signed-off-by: Prathyush K <prathyush.k@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.c |    8 ++++----
>  drivers/gpu/drm/exynos/exynos_drm_hdmi.h |    2 +-
>  drivers/gpu/drm/exynos/exynos_hdmi.c     |   24 ------------------------
>  drivers/gpu/drm/exynos/exynos_mixer.c    |   23 +++++++++++++++++++++++
>  4 files changed, 28 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> index 997fb6e..8b771a3 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
> @@ -368,8 +368,8 @@ static int hdmi_subdrv_probe(struct drm_device
> *drm_dev,
>         ctx->hdmi_ctx->drm_dev = drm_dev;
>         ctx->mixer_ctx->drm_dev = drm_dev;
>
> -       if (hdmi_ops->iommu_on)
> -               hdmi_ops->iommu_on(ctx->hdmi_ctx->ctx, true);
> +       if (mixer_ops->iommu_on)
> +               mixer_ops->iommu_on(ctx->mixer_ctx->ctx, true);
>
>         return 0;
>  }
> @@ -381,8 +381,8 @@ static void hdmi_subdrv_remove(struct drm_device
> *drm_dev, struct device *dev)
>
>         ctx = get_ctx_from_subdrv(subdrv);
>
> -       if (hdmi_ops->iommu_on)
> -               hdmi_ops->iommu_on(ctx->hdmi_ctx->ctx, false);
> +       if (mixer_ops->iommu_on)
> +               mixer_ops->iommu_on(ctx->mixer_ctx->ctx, false);
>  }
>
>  static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> index 5c033d1..54b5223 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
> @@ -50,7 +50,6 @@ struct exynos_hdmi_ops {
>         int (*power_on)(void *ctx, int mode);
>
>         /* manager */
> -       int (*iommu_on)(void *ctx, bool enable);
>         void (*mode_fixup)(void *ctx, struct drm_connector *connector,
>                                 const struct drm_display_mode *mode,
>                                 struct drm_display_mode *adjusted_mode);
> @@ -63,6 +62,7 @@ struct exynos_hdmi_ops {
>
>  struct exynos_mixer_ops {
>         /* manager */
> +       int (*iommu_on)(void *ctx, bool enable);
>         int (*enable_vblank)(void *ctx, int pipe);
>         void (*disable_vblank)(void *ctx);
>         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 d1a1d71..7df1d85 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -40,7 +40,6 @@
>
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_hdmi.h"
> -#include "exynos_drm_iommu.h"
>
>  #include "exynos_hdmi.h"
>
> @@ -68,7 +67,6 @@ struct hdmi_resources {
>
>  struct hdmi_context {
>         struct device                   *dev;
> -       struct drm_device               *drm_dev;
>

this one.


>         bool                            hpd;
>         bool                            powered;
>         bool                            dvi_mode;
> @@ -85,7 +83,6 @@ struct hdmi_context {
>         int cur_conf;
>
>         struct hdmi_resources           res;
> -       void                            *parent_ctx;
>

this one.



>
>         int                             hpd_gpio;
>
> @@ -1947,25 +1944,6 @@ static void hdmi_conf_apply(struct hdmi_context
> *hdata)
>         hdmi_regs_dump(hdata, "start");
>  }
>
> -static int hdmi_iommu_on(void *ctx, bool enable)
> -{
> -       struct exynos_drm_hdmi_context *drm_hdmi_ctx;
> -       struct hdmi_context *hdata = ctx;
> -       struct drm_device *drm_dev;
> -
> -       drm_hdmi_ctx = hdata->parent_ctx;
> -       drm_dev = drm_hdmi_ctx->drm_dev;
> -
> -       if (is_drm_iommu_supported(drm_dev)) {
> -               if (enable)
> -                       return drm_iommu_attach_device(drm_dev,
> hdata->dev);
> -
> -               drm_iommu_detach_device(drm_dev, hdata->dev);
> -       }
> -
> -       return 0;
> -}
> -
>  static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
>                                 const struct drm_display_mode *mode,
>                                 struct drm_display_mode *adjusted_mode)
> @@ -2122,7 +2100,6 @@ static struct exynos_hdmi_ops hdmi_ops = {
>         .check_timing   = hdmi_check_timing,
>
>         /* manager */
> -       .iommu_on       = hdmi_iommu_on,
>         .mode_fixup     = hdmi_mode_fixup,
>         .mode_set       = hdmi_mode_set,
>         .get_max_resol  = hdmi_get_max_resol,
> @@ -2379,7 +2356,6 @@ static int __devinit hdmi_probe(struct
> platform_device *pdev)
>         mutex_init(&hdata->hdmi_mutex);
>
>         drm_hdmi_ctx->ctx = (void *)hdata;
> -       hdata->parent_ctx = (void *)drm_hdmi_ctx;
>

this one.


>
>         platform_set_drvdata(pdev, drm_hdmi_ctx);
>
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c
> b/drivers/gpu/drm/exynos/exynos_mixer.c
> index 614b2e9..574ed3f 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -36,6 +36,7 @@
>
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_hdmi.h"
> +#include "exynos_drm_iommu.h"
>
>  #define get_mixer_context(dev)
> platform_get_drvdata(to_platform_device(dev))
>
> @@ -80,6 +81,7 @@ enum mixer_version_id {
>
>  struct mixer_context {
>         struct device           *dev;
> +       struct drm_device       *drm_dev;
>         int                     pipe;
>         bool                    interlace;
>         bool                    powered;
> @@ -90,6 +92,7 @@ struct mixer_context {
>         struct mixer_resources  mixer_res;
>         struct hdmi_win_data    win_data[MIXER_WIN_NR];
>         enum mixer_version_id   mxr_ver;
> +       void                    *parent_ctx;
>  };
>
>  struct mixer_drv_data {
> @@ -665,6 +668,24 @@ static void mixer_win_reset(struct mixer_context *ctx)
>         spin_unlock_irqrestore(&res->reg_slock, flags);
>  }
>
> +static int mixer_iommu_on(void *ctx, bool enable)
> +{
> +       struct exynos_drm_hdmi_context *drm_hdmi_ctx;
> +       struct mixer_context *mdata = ctx;
> +       struct drm_device *drm_dev;
> +
> +       drm_hdmi_ctx = mdata->parent_ctx;
> +       drm_dev = drm_hdmi_ctx->drm_dev;
> +
> +       if (is_drm_iommu_supported(drm_dev)) {
> +               if (enable)
> +                       return drm_iommu_attach_device(drm_dev,
> mdata->dev);
> +
> +               drm_iommu_detach_device(drm_dev, mdata->dev);
> +       }
> +       return 0;
> +}
> +
>  static void mixer_poweron(struct mixer_context *ctx)
>  {
>         struct mixer_resources *res = &ctx->mixer_res;
> @@ -866,6 +887,7 @@ static void mixer_win_disable(void *ctx, int win)
>
>  static struct exynos_mixer_ops mixer_ops = {
>         /* manager */
> +       .iommu_on               = mixer_iommu_on,
>         .enable_vblank          = mixer_enable_vblank,
>         .disable_vblank         = mixer_disable_vblank,
>         .dpms                   = mixer_dpms,
> @@ -1149,6 +1171,7 @@ static int __devinit mixer_probe(struct
> platform_device *pdev)
>         }
>
>         ctx->dev = &pdev->dev;
> +       ctx->parent_ctx = (void *)drm_hdmi_ctx;
>         drm_hdmi_ctx->ctx = (void *)ctx;
>         ctx->vp_enabled = drv->is_vp_enabled;
>         ctx->mxr_ver = drv->version;
> --
> 1.7.0.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index 997fb6e..8b771a3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -368,8 +368,8 @@  static int hdmi_subdrv_probe(struct drm_device *drm_dev,
 	ctx->hdmi_ctx->drm_dev = drm_dev;
 	ctx->mixer_ctx->drm_dev = drm_dev;
 
-	if (hdmi_ops->iommu_on)
-		hdmi_ops->iommu_on(ctx->hdmi_ctx->ctx, true);
+	if (mixer_ops->iommu_on)
+		mixer_ops->iommu_on(ctx->mixer_ctx->ctx, true);
 
 	return 0;
 }
@@ -381,8 +381,8 @@  static void hdmi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 
 	ctx = get_ctx_from_subdrv(subdrv);
 
-	if (hdmi_ops->iommu_on)
-		hdmi_ops->iommu_on(ctx->hdmi_ctx->ctx, false);
+	if (mixer_ops->iommu_on)
+		mixer_ops->iommu_on(ctx->mixer_ctx->ctx, false);
 }
 
 static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 5c033d1..54b5223 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -50,7 +50,6 @@  struct exynos_hdmi_ops {
 	int (*power_on)(void *ctx, int mode);
 
 	/* manager */
-	int (*iommu_on)(void *ctx, bool enable);
 	void (*mode_fixup)(void *ctx, struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode);
@@ -63,6 +62,7 @@  struct exynos_hdmi_ops {
 
 struct exynos_mixer_ops {
 	/* manager */
+	int (*iommu_on)(void *ctx, bool enable);
 	int (*enable_vblank)(void *ctx, int pipe);
 	void (*disable_vblank)(void *ctx);
 	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 d1a1d71..7df1d85 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -40,7 +40,6 @@ 
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_hdmi.h"
-#include "exynos_drm_iommu.h"
 
 #include "exynos_hdmi.h"
 
@@ -68,7 +67,6 @@  struct hdmi_resources {
 
 struct hdmi_context {
 	struct device			*dev;
-	struct drm_device		*drm_dev;
 	bool				hpd;
 	bool				powered;
 	bool				dvi_mode;
@@ -85,7 +83,6 @@  struct hdmi_context {
 	int cur_conf;
 
 	struct hdmi_resources		res;
-	void				*parent_ctx;
 
 	int				hpd_gpio;
 
@@ -1947,25 +1944,6 @@  static void hdmi_conf_apply(struct hdmi_context *hdata)
 	hdmi_regs_dump(hdata, "start");
 }
 
-static int hdmi_iommu_on(void *ctx, bool enable)
-{
-	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
-	struct hdmi_context *hdata = ctx;
-	struct drm_device *drm_dev;
-
-	drm_hdmi_ctx = hdata->parent_ctx;
-	drm_dev = drm_hdmi_ctx->drm_dev;
-
-	if (is_drm_iommu_supported(drm_dev)) {
-		if (enable)
-			return drm_iommu_attach_device(drm_dev, hdata->dev);
-
-		drm_iommu_detach_device(drm_dev, hdata->dev);
-	}
-
-	return 0;
-}
-
 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
@@ -2122,7 +2100,6 @@  static struct exynos_hdmi_ops hdmi_ops = {
 	.check_timing	= hdmi_check_timing,
 
 	/* manager */
-	.iommu_on	= hdmi_iommu_on,
 	.mode_fixup	= hdmi_mode_fixup,
 	.mode_set	= hdmi_mode_set,
 	.get_max_resol	= hdmi_get_max_resol,
@@ -2379,7 +2356,6 @@  static int __devinit hdmi_probe(struct platform_device *pdev)
 	mutex_init(&hdata->hdmi_mutex);
 
 	drm_hdmi_ctx->ctx = (void *)hdata;
-	hdata->parent_ctx = (void *)drm_hdmi_ctx;
 
 	platform_set_drvdata(pdev, drm_hdmi_ctx);
 
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 614b2e9..574ed3f 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -36,6 +36,7 @@ 
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_hdmi.h"
+#include "exynos_drm_iommu.h"
 
 #define get_mixer_context(dev)	platform_get_drvdata(to_platform_device(dev))
 
@@ -80,6 +81,7 @@  enum mixer_version_id {
 
 struct mixer_context {
 	struct device		*dev;
+	struct drm_device	*drm_dev;
 	int			pipe;
 	bool			interlace;
 	bool			powered;
@@ -90,6 +92,7 @@  struct mixer_context {
 	struct mixer_resources	mixer_res;
 	struct hdmi_win_data	win_data[MIXER_WIN_NR];
 	enum mixer_version_id	mxr_ver;
+	void			*parent_ctx;
 };
 
 struct mixer_drv_data {
@@ -665,6 +668,24 @@  static void mixer_win_reset(struct mixer_context *ctx)
 	spin_unlock_irqrestore(&res->reg_slock, flags);
 }
 
+static int mixer_iommu_on(void *ctx, bool enable)
+{
+	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
+	struct mixer_context *mdata = ctx;
+	struct drm_device *drm_dev;
+
+	drm_hdmi_ctx = mdata->parent_ctx;
+	drm_dev = drm_hdmi_ctx->drm_dev;
+
+	if (is_drm_iommu_supported(drm_dev)) {
+		if (enable)
+			return drm_iommu_attach_device(drm_dev, mdata->dev);
+
+		drm_iommu_detach_device(drm_dev, mdata->dev);
+	}
+	return 0;
+}
+
 static void mixer_poweron(struct mixer_context *ctx)
 {
 	struct mixer_resources *res = &ctx->mixer_res;
@@ -866,6 +887,7 @@  static void mixer_win_disable(void *ctx, int win)
 
 static struct exynos_mixer_ops mixer_ops = {
 	/* manager */
+	.iommu_on		= mixer_iommu_on,
 	.enable_vblank		= mixer_enable_vblank,
 	.disable_vblank		= mixer_disable_vblank,
 	.dpms			= mixer_dpms,
@@ -1149,6 +1171,7 @@  static int __devinit mixer_probe(struct platform_device *pdev)
 	}
 
 	ctx->dev = &pdev->dev;
+	ctx->parent_ctx = (void *)drm_hdmi_ctx;
 	drm_hdmi_ctx->ctx = (void *)ctx;
 	ctx->vp_enabled = drv->is_vp_enabled;
 	ctx->mxr_ver = drv->version;