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>
This commit is contained in:
parent
bcc5cd1c5f
commit
1055b39fac
|
@ -346,9 +346,23 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
|
||||||
ctx->hdmi_ctx->drm_dev = drm_dev;
|
ctx->hdmi_ctx->drm_dev = drm_dev;
|
||||||
ctx->mixer_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;
|
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)
|
static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
@ -368,6 +382,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
|
||||||
subdrv->dev = dev;
|
subdrv->dev = dev;
|
||||||
subdrv->manager = &hdmi_manager;
|
subdrv->manager = &hdmi_manager;
|
||||||
subdrv->probe = hdmi_subdrv_probe;
|
subdrv->probe = hdmi_subdrv_probe;
|
||||||
|
subdrv->remove = hdmi_subdrv_remove;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, subdrv);
|
platform_set_drvdata(pdev, subdrv);
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct exynos_hdmi_ops {
|
||||||
|
|
||||||
struct exynos_mixer_ops {
|
struct exynos_mixer_ops {
|
||||||
/* manager */
|
/* manager */
|
||||||
|
int (*iommu_on)(void *ctx, bool enable);
|
||||||
int (*enable_vblank)(void *ctx, int pipe);
|
int (*enable_vblank)(void *ctx, int pipe);
|
||||||
void (*disable_vblank)(void *ctx);
|
void (*disable_vblank)(void *ctx);
|
||||||
void (*dpms)(void *ctx, int mode);
|
void (*dpms)(void *ctx, int mode);
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct hdmi_context {
|
||||||
struct mutex hdmi_mutex;
|
struct mutex hdmi_mutex;
|
||||||
|
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
|
void *parent_ctx;
|
||||||
int external_irq;
|
int external_irq;
|
||||||
int internal_irq;
|
int internal_irq;
|
||||||
|
|
||||||
|
@ -84,7 +85,6 @@ struct hdmi_context {
|
||||||
int cur_conf;
|
int cur_conf;
|
||||||
|
|
||||||
struct hdmi_resources res;
|
struct hdmi_resources res;
|
||||||
void *parent_ctx;
|
|
||||||
|
|
||||||
int hpd_gpio;
|
int hpd_gpio;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_hdmi.h"
|
#include "exynos_drm_hdmi.h"
|
||||||
|
#include "exynos_drm_iommu.h"
|
||||||
|
|
||||||
#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
|
#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ enum mixer_version_id {
|
||||||
|
|
||||||
struct mixer_context {
|
struct mixer_context {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct drm_device *drm_dev;
|
||||||
int pipe;
|
int pipe;
|
||||||
bool interlace;
|
bool interlace;
|
||||||
bool powered;
|
bool powered;
|
||||||
|
@ -90,6 +92,7 @@ struct mixer_context {
|
||||||
struct mixer_resources mixer_res;
|
struct mixer_resources mixer_res;
|
||||||
struct hdmi_win_data win_data[MIXER_WIN_NR];
|
struct hdmi_win_data win_data[MIXER_WIN_NR];
|
||||||
enum mixer_version_id mxr_ver;
|
enum mixer_version_id mxr_ver;
|
||||||
|
void *parent_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mixer_drv_data {
|
struct mixer_drv_data {
|
||||||
|
@ -665,6 +668,24 @@ static void mixer_win_reset(struct mixer_context *ctx)
|
||||||
spin_unlock_irqrestore(&res->reg_slock, flags);
|
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)
|
static void mixer_poweron(struct mixer_context *ctx)
|
||||||
{
|
{
|
||||||
struct mixer_resources *res = &ctx->mixer_res;
|
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 = {
|
static struct exynos_mixer_ops mixer_ops = {
|
||||||
/* manager */
|
/* manager */
|
||||||
|
.iommu_on = mixer_iommu_on,
|
||||||
.enable_vblank = mixer_enable_vblank,
|
.enable_vblank = mixer_enable_vblank,
|
||||||
.disable_vblank = mixer_disable_vblank,
|
.disable_vblank = mixer_disable_vblank,
|
||||||
.dpms = mixer_dpms,
|
.dpms = mixer_dpms,
|
||||||
|
@ -1140,6 +1162,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->dev = &pdev->dev;
|
ctx->dev = &pdev->dev;
|
||||||
|
ctx->parent_ctx = (void *)drm_hdmi_ctx;
|
||||||
drm_hdmi_ctx->ctx = (void *)ctx;
|
drm_hdmi_ctx->ctx = (void *)ctx;
|
||||||
ctx->vp_enabled = drv->is_vp_enabled;
|
ctx->vp_enabled = drv->is_vp_enabled;
|
||||||
ctx->mxr_ver = drv->version;
|
ctx->mxr_ver = drv->version;
|
||||||
|
|
Loading…
Reference in New Issue