This patch adds device tree based IOMMU support to DRM FIMD. During probe, the driver searches for a 'sysmmu' field in the device node. The sysmmu field points to the corresponding sysmmu device of fimd. This sysmmu device is retrieved and set as fimd's sysmmu. The common IOMMU mapping created during DRM init is then attached to drm fimd. Signed-off-by: Prathyush K <prathyush.k@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 54 +++++++++++++++++++++++++++++- 1 files changed, 53 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 15b5286..6d4048a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -19,7 +19,7 @@ #include <linux/clk.h> #include <linux/pm_runtime.h> #include <linux/of.h> - +#include <linux/of_platform.h> #include <drm/exynos_drm.h> #include <plat/regs-fb-v4.h> @@ -790,12 +790,56 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable) } #ifdef CONFIG_OF + +#ifdef CONFIG_EXYNOS_IOMMU +static int iommu_init(struct device *dev) +{ + struct platform_device *pds; + struct device_node *dn, *dns; + const __be32 *parp; + int ret; + + dn = dev->of_node; + parp = of_get_property(dn, "sysmmu", NULL); + if (parp == NULL) { + dev_err(dev, "failed to find sysmmu property\n"); + return -EINVAL; + } + dns = of_find_node_by_phandle(be32_to_cpup(parp)); + if (dns == NULL) { + dev_err(dev, "failed to find sysmmu node\n"); + return -EINVAL; + } + pds = of_find_device_by_node(dns); + if (pds == NULL) { + dev_err(dev, "failed to find sysmmu platform device\n"); + return -EINVAL; + } + + platform_set_sysmmu(&pds->dev, dev); + dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL); + if (!dev->dma_parms) { + dev_err(dev, "failed to allocate dma parms\n"); + return -ENOMEM; + } + dma_set_max_seg_size(dev, 0xffffffffu); + + ret = arm_iommu_attach_device(dev, exynos_drm_common_mapping); + if (ret) { + dev_err(dev, "failed to attach device\n"); + return ret; + } + return 0; +} +#endif + static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) { struct device_node *np = dev->of_node; struct device_node *disp_np; struct exynos_drm_fimd_pdata *pd; u32 data[4]; + int ret; pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { @@ -803,6 +847,14 @@ static struct exynos_drm_fimd_pdata *drm_fimd_dt_parse_pdata(struct device *dev) return ERR_PTR(-ENOMEM); } +#ifdef CONFIG_EXYNOS_IOMMU + ret = iommu_init(dev); + if (ret) { + dev_err(dev, "failed to initialize iommu\n"); + return ERR_PTR(ret); + } +#endif + if (of_get_property(np, "samsung,fimd-vidout-rgb", NULL)) pd->vidcon0 |= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB; if (of_get_property(np, "samsung,fimd-vidout-tv", NULL)) -- 1.7.0.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel