drm/exynos: simplify DMA mapping
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>
This commit is contained in:
parent
167bfe534d
commit
29cbf24a4d
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -45,6 +45,27 @@
|
|||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue