drm/exynos: simplify DMA mapping
authorAndrzej Hajda <a.hajda@samsung.com>
Fri, 12 Oct 2018 10:53:41 +0000 (12:53 +0200)
committerInki Dae <inki.dae@samsung.com>
Tue, 4 Dec 2018 04:23:17 +0000 (13:23 +0900)
Moving DMA mapping creation to drm_iommu_attach_device allows to avoid
looping through all components and maintaining DMA device flags.

v2: take care of configurations without IOMMU

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimc.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/exynos_drm_rotator.c
drivers/gpu/drm/exynos/exynos_drm_scaler.c
drivers/gpu/drm/exynos/exynos_mixer.c

index aef487d..ce08d77 100644 (file)
@@ -569,7 +569,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 
        decon_clear_channels(ctx->crtc);
 
-       return drm_iommu_attach_device(drm_dev, dev);
+       return exynos_drm_register_dma(drm_dev, dev);
 }
 
 static void decon_unbind(struct device *dev, struct device *master, void *data)
index 88cbd00..e78978e 100644 (file)
@@ -133,7 +133,7 @@ static int decon_ctx_initialize(struct decon_context *ctx,
 
        decon_clear_channels(ctx->crtc);
 
-       return drm_iommu_attach_device(drm_dev, ctx->dev);
+       return exynos_drm_register_dma(drm_dev, ctx->dev);
 }
 
 static void decon_ctx_remove(struct decon_context *ctx)
index 6f76baf..3cf21d8 100644 (file)
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   1
 
+int exynos_drm_register_dma(struct drm_device *drm, struct device *dev)
+{
+       struct exynos_drm_private *priv = drm->dev_private;
+       int ret;
+
+       if (!priv->dma_dev) {
+               priv->dma_dev = dev;
+               DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
+                        dev_name(dev));
+               /* create common IOMMU mapping for all Exynos DRM devices */
+               ret = drm_create_iommu_mapping(drm);
+               if (ret < 0) {
+                       priv->dma_dev = NULL;
+                       DRM_ERROR("failed to create iommu mapping.\n");
+                       return -EINVAL;
+               }
+       }
+
+       return drm_iommu_attach_device(drm, dev);
+}
+
 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
        struct drm_exynos_file_private *file_priv;
@@ -175,8 +196,7 @@ struct exynos_drm_driver_info {
 
 #define DRM_COMPONENT_DRIVER   BIT(0)  /* supports component framework */
 #define DRM_VIRTUAL_DEVICE     BIT(1)  /* create virtual platform device */
-#define DRM_DMA_DEVICE         BIT(2)  /* can be used for dma allocations */
-#define DRM_FIMC_DEVICE                BIT(3)  /* devices shared with V4L2 subsystem */
+#define DRM_FIMC_DEVICE                BIT(2)  /* devices shared with V4L2 subsystem */
 
 #define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL)
 
@@ -187,16 +207,16 @@ struct exynos_drm_driver_info {
 static struct exynos_drm_driver_info exynos_drm_drivers[] = {
        {
                DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD),
-               DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+               DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(exynos5433_decon_driver, CONFIG_DRM_EXYNOS5433_DECON),
-               DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+               DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(decon_driver, CONFIG_DRM_EXYNOS7_DECON),
-               DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+               DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
-               DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+               DRM_COMPONENT_DRIVER
        }, {
                DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
                DRM_COMPONENT_DRIVER
@@ -267,27 +287,6 @@ static struct component_match *exynos_drm_match_add(struct device *dev)
        return match ?: ERR_PTR(-ENODEV);
 }
 
-static struct device *exynos_drm_get_dma_device(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
-               struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
-               struct device *dev;
-
-               if (!info->driver || !(info->flags & DRM_DMA_DEVICE))
-                       continue;
-
-               while ((dev = bus_find_device(&platform_bus_type, NULL,
-                                           &info->driver->driver,
-                                           (void *)platform_bus_type.match))) {
-                       put_device(dev);
-                       return dev;
-               }
-       }
-       return NULL;
-}
-
 static int exynos_drm_bind(struct device *dev)
 {
        struct exynos_drm_private *private;
@@ -312,23 +311,6 @@ static int exynos_drm_bind(struct device *dev)
        dev_set_drvdata(dev, drm);
        drm->dev_private = (void *)private;
 
-       /* the first real CRTC device is used for all dma mapping operations */
-       private->dma_dev = exynos_drm_get_dma_device();
-       if (!private->dma_dev) {
-               DRM_ERROR("no device found for DMA mapping operations.\n");
-               ret = -ENODEV;
-               goto err_free_private;
-       }
-       DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
-                dev_name(private->dma_dev));
-
-       /* create common IOMMU mapping for all devices attached to Exynos DRM */
-       ret = drm_create_iommu_mapping(drm);
-       if (ret < 0) {
-               DRM_ERROR("failed to create iommu mapping.\n");
-               goto err_free_private;
-       }
-
        drm_mode_config_init(drm);
 
        exynos_drm_mode_config_init(drm);
@@ -386,7 +368,6 @@ err_unbind_all:
 err_mode_config_cleanup:
        drm_mode_config_cleanup(drm);
        drm_release_iommu_mapping(drm);
-err_free_private:
        kfree(private);
 err_free_drm:
        drm_dev_put(drm);
index 5e61e70..1d4c3c4 100644 (file)
@@ -214,6 +214,8 @@ static inline struct device *to_dma_dev(struct drm_device *dev)
        return priv->dma_dev;
 }
 
+int exynos_drm_register_dma(struct drm_device *drm, struct device *dev);
+
 #ifdef CONFIG_DRM_EXYNOS_DPI
 struct drm_encoder *exynos_dpi_probe(struct device *dev);
 int exynos_dpi_remove(struct drm_encoder *encoder);
index e8d0670..68bfe2c 100644 (file)
@@ -1129,7 +1129,7 @@ static int fimc_bind(struct device *dev, struct device *master, void *data)
        struct exynos_drm_ipp *ipp = &ctx->ipp;
 
        ctx->drm_dev = drm_dev;
-       drm_iommu_attach_device(drm_dev, dev);
+       exynos_drm_register_dma(drm_dev, dev);
 
        exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
                        DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
index b7f5693..5b3d514 100644 (file)
@@ -1011,7 +1011,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
        if (is_drm_iommu_supported(drm_dev))
                fimd_clear_channels(ctx->crtc);
 
-       return drm_iommu_attach_device(drm_dev, dev);
+       return exynos_drm_register_dma(drm_dev, dev);
 }
 
 static void fimd_unbind(struct device *dev, struct device *master,
index f2481a2..86624ec 100644 (file)
@@ -1405,7 +1405,7 @@ static int g2d_bind(struct device *dev, struct device *master, void *data)
                return ret;
        }
 
-       ret = drm_iommu_attach_device(drm_dev, dev);
+       ret = exynos_drm_register_dma(drm_dev, dev);
        if (ret < 0) {
                dev_err(dev, "failed to enable iommu.\n");
                g2d_fini_cmdlist(g2d);
index ce15d46..d2607da 100644 (file)
@@ -1170,7 +1170,7 @@ static int gsc_bind(struct device *dev, struct device *master, void *data)
        struct exynos_drm_ipp *ipp = &ctx->ipp;
 
        ctx->drm_dev = drm_dev;
-       drm_iommu_attach_device(drm_dev, dev);
+       exynos_drm_register_dma(drm_dev, dev);
 
        exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
                        DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
index a820a68..7d4b5a1 100644 (file)
@@ -244,7 +244,7 @@ static int rotator_bind(struct device *dev, struct device *master, void *data)
        struct exynos_drm_ipp *ipp = &rot->ipp;
 
        rot->drm_dev = drm_dev;
-       drm_iommu_attach_device(drm_dev, dev);
+       exynos_drm_register_dma(drm_dev, dev);
 
        exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
                           DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE,
index cd66774..74e761c 100644 (file)
@@ -452,7 +452,7 @@ static int scaler_bind(struct device *dev, struct device *master, void *data)
        struct exynos_drm_ipp *ipp = &scaler->ipp;
 
        scaler->drm_dev = drm_dev;
-       drm_iommu_attach_device(drm_dev, dev);
+       exynos_drm_register_dma(drm_dev, dev);
 
        exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs,
                        DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
index e3a4ecb..52193de 100644 (file)
@@ -878,7 +878,7 @@ static int mixer_initialize(struct mixer_context *mixer_ctx,
                }
        }
 
-       return drm_iommu_attach_device(drm_dev, mixer_ctx->dev);
+       return exynos_drm_register_dma(drm_dev, mixer_ctx->dev);
 }
 
 static void mixer_ctx_remove(struct mixer_context *mixer_ctx)