Skip to content

Commit

Permalink
drm/exynos: add iommu support for hdmi driver
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Inki Dae committed Dec 4, 2012
1 parent bcc5cd1 commit 1055b39
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 1 deletion.
15 changes: 15 additions & 0 deletions drivers/gpu/drm/exynos/exynos_drm_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,23 @@ 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 (mixer_ops->iommu_on)
mixer_ops->iommu_on(ctx->mixer_ctx->ctx, true);

return 0;
}

static void hdmi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
{
struct drm_hdmi_context *ctx;
struct exynos_drm_subdrv *subdrv = to_subdrv(dev);

ctx = get_ctx_from_subdrv(subdrv);

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)
{
struct device *dev = &pdev->dev;
Expand All @@ -368,6 +382,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
subdrv->dev = dev;
subdrv->manager = &hdmi_manager;
subdrv->probe = hdmi_subdrv_probe;
subdrv->remove = hdmi_subdrv_remove;

platform_set_drvdata(pdev, subdrv);

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/exynos/exynos_drm_hdmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/exynos/exynos_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct hdmi_context {
struct mutex hdmi_mutex;

void __iomem *regs;
void *parent_ctx;
int external_irq;
int internal_irq;

Expand All @@ -84,7 +85,6 @@ struct hdmi_context {
int cur_conf;

struct hdmi_resources res;
void *parent_ctx;

int hpd_gpio;

Expand Down
23 changes: 23 additions & 0 deletions drivers/gpu/drm/exynos/exynos_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -1140,6 +1162,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;
Expand Down

0 comments on commit 1055b39

Please sign in to comment.