forked from Minki/linux
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->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;
|
||||
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -74,6 +74,7 @@ struct hdmi_context {
|
||||
struct mutex hdmi_mutex;
|
||||
|
||||
void __iomem *regs;
|
||||
void *parent_ctx;
|
||||
int external_irq;
|
||||
int internal_irq;
|
||||
|
||||
@ -84,7 +85,6 @@ struct hdmi_context {
|
||||
int cur_conf;
|
||||
|
||||
struct hdmi_resources res;
|
||||
void *parent_ctx;
|
||||
|
||||
int hpd_gpio;
|
||||
|
||||
|
@ -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,
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user