mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
drm/exynos/iommu: integrate IOMMU/DMA internal API
Exynos DRM drivers should work with and without IOMMU. Providing common API generic to both scenarios should make code cleaner and allow further code improvements. The patch removes including of exynos_drm_iommu.h as the file contains mostly IOMMU specific stuff, instead it exposes exynos_drm_*_dma functions and puts them into exynos_drm_dma.c. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
69908ed258
commit
237556962e
17 changed files with 61 additions and 58 deletions
|
@ -4,7 +4,7 @@
|
||||||
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
|
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
|
||||||
|
|
||||||
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
|
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
|
||||||
exynos_drm_gem.o exynos_drm_plane.o
|
exynos_drm_gem.o exynos_drm_plane.o exynos_drm_dma.o
|
||||||
|
|
||||||
exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
|
exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
|
||||||
exynosdrm-$(CONFIG_EXYNOS_IOMMU) += exynos_drm_iommu.o
|
exynosdrm-$(CONFIG_EXYNOS_IOMMU) += exynos_drm_iommu.o
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "exynos_drm_crtc.h"
|
#include "exynos_drm_crtc.h"
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_plane.h"
|
#include "exynos_drm_plane.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "regs-decon5433.h"
|
#include "regs-decon5433.h"
|
||||||
|
|
||||||
#define DSD_CFG_MUX 0x1004
|
#define DSD_CFG_MUX 0x1004
|
||||||
|
@ -579,7 +578,7 @@ static void decon_unbind(struct device *dev, struct device *master, void *data)
|
||||||
decon_disable(ctx->crtc);
|
decon_disable(ctx->crtc);
|
||||||
|
|
||||||
/* detach this sub driver from iommu mapping if supported. */
|
/* detach this sub driver from iommu mapping if supported. */
|
||||||
drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
|
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops decon_component_ops = {
|
static const struct component_ops decon_component_ops = {
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include "exynos_drm_plane.h"
|
#include "exynos_drm_plane.h"
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "regs-decon7.h"
|
#include "regs-decon7.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -139,7 +138,7 @@ static int decon_ctx_initialize(struct decon_context *ctx,
|
||||||
static void decon_ctx_remove(struct decon_context *ctx)
|
static void decon_ctx_remove(struct decon_context *ctx)
|
||||||
{
|
{
|
||||||
/* detach this sub driver from iommu mapping if supported. */
|
/* detach this sub driver from iommu mapping if supported. */
|
||||||
drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
|
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 decon_calc_clkdiv(struct decon_context *ctx,
|
static u32 decon_calc_clkdiv(struct decon_context *ctx,
|
||||||
|
|
40
drivers/gpu/drm/exynos/exynos_drm_dma.c
Normal file
40
drivers/gpu/drm/exynos/exynos_drm_dma.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 Samsung Electronics Co., Ltd.
|
||||||
|
// Author: Andrzej Hajda <a.hajda@samsung.com>
|
||||||
|
|
||||||
|
#include "exynos_drm_drv.h"
|
||||||
|
#include "exynos_drm_iommu.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_EXYNOS_IOMMU))
|
||||||
|
drm_iommu_detach_device(drm, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exynos_drm_cleanup_dma(struct drm_device *drm)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_EXYNOS_IOMMU))
|
||||||
|
drm_release_iommu_mapping(drm);
|
||||||
|
}
|
|
@ -30,7 +30,6 @@
|
||||||
#include "exynos_drm_ipp.h"
|
#include "exynos_drm_ipp.h"
|
||||||
#include "exynos_drm_vidi.h"
|
#include "exynos_drm_vidi.h"
|
||||||
#include "exynos_drm_g2d.h"
|
#include "exynos_drm_g2d.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
|
|
||||||
#define DRIVER_NAME "exynos"
|
#define DRIVER_NAME "exynos"
|
||||||
#define DRIVER_DESC "Samsung SoC DRM"
|
#define DRIVER_DESC "Samsung SoC DRM"
|
||||||
|
@ -45,27 +44,6 @@
|
||||||
#define DRIVER_MAJOR 1
|
#define DRIVER_MAJOR 1
|
||||||
#define DRIVER_MINOR 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)
|
static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
|
||||||
{
|
{
|
||||||
struct drm_exynos_file_private *file_priv;
|
struct drm_exynos_file_private *file_priv;
|
||||||
|
@ -367,7 +345,7 @@ static int exynos_drm_bind(struct device *dev)
|
||||||
component_unbind_all(drm->dev, drm);
|
component_unbind_all(drm->dev, drm);
|
||||||
err_mode_config_cleanup:
|
err_mode_config_cleanup:
|
||||||
drm_mode_config_cleanup(drm);
|
drm_mode_config_cleanup(drm);
|
||||||
drm_release_iommu_mapping(drm);
|
exynos_drm_cleanup_dma(drm);
|
||||||
kfree(private);
|
kfree(private);
|
||||||
err_free_drm:
|
err_free_drm:
|
||||||
drm_dev_put(drm);
|
drm_dev_put(drm);
|
||||||
|
@ -386,7 +364,7 @@ static void exynos_drm_unbind(struct device *dev)
|
||||||
|
|
||||||
component_unbind_all(drm->dev, drm);
|
component_unbind_all(drm->dev, drm);
|
||||||
drm_mode_config_cleanup(drm);
|
drm_mode_config_cleanup(drm);
|
||||||
drm_release_iommu_mapping(drm);
|
exynos_drm_cleanup_dma(drm);
|
||||||
|
|
||||||
kfree(drm->dev_private);
|
kfree(drm->dev_private);
|
||||||
drm->dev_private = NULL;
|
drm->dev_private = NULL;
|
||||||
|
|
|
@ -214,7 +214,16 @@ static inline struct device *to_dma_dev(struct drm_device *dev)
|
||||||
return priv->dma_dev;
|
return priv->dma_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
|
||||||
|
{
|
||||||
|
struct exynos_drm_private *priv = drm_dev->dev_private;
|
||||||
|
|
||||||
|
return priv->mapping ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
int exynos_drm_register_dma(struct drm_device *drm, struct device *dev);
|
int exynos_drm_register_dma(struct drm_device *drm, struct device *dev);
|
||||||
|
void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev);
|
||||||
|
void exynos_drm_cleanup_dma(struct drm_device *drm);
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_EXYNOS_DPI
|
#ifdef CONFIG_DRM_EXYNOS_DPI
|
||||||
struct drm_encoder *exynos_dpi_probe(struct device *dev);
|
struct drm_encoder *exynos_dpi_probe(struct device *dev);
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_fbdev.h"
|
#include "exynos_drm_fbdev.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "exynos_drm_crtc.h"
|
#include "exynos_drm_crtc.h"
|
||||||
|
|
||||||
static int check_fb_gem_memory_type(struct drm_device *drm_dev,
|
static int check_fb_gem_memory_type(struct drm_device *drm_dev,
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_fbdev.h"
|
#include "exynos_drm_fbdev.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
|
|
||||||
#define MAX_CONNECTOR 4
|
#define MAX_CONNECTOR 4
|
||||||
#define PREFERRED_BPP 32
|
#define PREFERRED_BPP 32
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <drm/exynos_drm.h>
|
#include <drm/exynos_drm.h>
|
||||||
#include "regs-fimc.h"
|
#include "regs-fimc.h"
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "exynos_drm_ipp.h"
|
#include "exynos_drm_ipp.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1149,7 +1148,7 @@ static void fimc_unbind(struct device *dev, struct device *master,
|
||||||
struct exynos_drm_ipp *ipp = &ctx->ipp;
|
struct exynos_drm_ipp *ipp = &ctx->ipp;
|
||||||
|
|
||||||
exynos_drm_ipp_unregister(drm_dev, ipp);
|
exynos_drm_ipp_unregister(drm_dev, ipp);
|
||||||
drm_iommu_detach_device(drm_dev, dev);
|
exynos_drm_unregister_dma(drm_dev, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops fimc_component_ops = {
|
static const struct component_ops fimc_component_ops = {
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_crtc.h"
|
#include "exynos_drm_crtc.h"
|
||||||
#include "exynos_drm_plane.h"
|
#include "exynos_drm_plane.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIMD stands for Fully Interactive Mobile Display and
|
* FIMD stands for Fully Interactive Mobile Display and
|
||||||
|
@ -1021,7 +1020,7 @@ static void fimd_unbind(struct device *dev, struct device *master,
|
||||||
|
|
||||||
fimd_disable(ctx->crtc);
|
fimd_disable(ctx->crtc);
|
||||||
|
|
||||||
drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
|
exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
|
||||||
|
|
||||||
if (ctx->encoder)
|
if (ctx->encoder)
|
||||||
exynos_dpi_remove(ctx->encoder);
|
exynos_dpi_remove(ctx->encoder);
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_g2d.h"
|
#include "exynos_drm_g2d.h"
|
||||||
#include "exynos_drm_gem.h"
|
#include "exynos_drm_gem.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
|
|
||||||
#define G2D_HW_MAJOR_VER 4
|
#define G2D_HW_MAJOR_VER 4
|
||||||
#define G2D_HW_MINOR_VER 1
|
#define G2D_HW_MINOR_VER 1
|
||||||
|
@ -1430,7 +1429,7 @@ static void g2d_unbind(struct device *dev, struct device *master, void *data)
|
||||||
priv->g2d_dev = NULL;
|
priv->g2d_dev = NULL;
|
||||||
|
|
||||||
cancel_work_sync(&g2d->runqueue_work);
|
cancel_work_sync(&g2d->runqueue_work);
|
||||||
drm_iommu_detach_device(g2d->drm_dev, dev);
|
exynos_drm_unregister_dma(g2d->drm_dev, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops g2d_component_ops = {
|
static const struct component_ops g2d_component_ops = {
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_gem.h"
|
#include "exynos_drm_gem.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
|
|
||||||
static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
|
static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <drm/exynos_drm.h>
|
#include <drm/exynos_drm.h>
|
||||||
#include "regs-gsc.h"
|
#include "regs-gsc.h"
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "exynos_drm_ipp.h"
|
#include "exynos_drm_ipp.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1190,7 +1189,7 @@ static void gsc_unbind(struct device *dev, struct device *master,
|
||||||
struct exynos_drm_ipp *ipp = &ctx->ipp;
|
struct exynos_drm_ipp *ipp = &ctx->ipp;
|
||||||
|
|
||||||
exynos_drm_ipp_unregister(drm_dev, ipp);
|
exynos_drm_ipp_unregister(drm_dev, ipp);
|
||||||
drm_iommu_detach_device(drm_dev, dev);
|
exynos_drm_unregister_dma(drm_dev, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops gsc_component_ops = {
|
static const struct component_ops gsc_component_ops = {
|
||||||
|
|
|
@ -96,13 +96,6 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
|
||||||
void drm_iommu_detach_device(struct drm_device *dev_dev,
|
void drm_iommu_detach_device(struct drm_device *dev_dev,
|
||||||
struct device *subdrv_dev);
|
struct device *subdrv_dev);
|
||||||
|
|
||||||
static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
|
|
||||||
{
|
|
||||||
struct exynos_drm_private *priv = drm_dev->dev_private;
|
|
||||||
|
|
||||||
return priv->mapping ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)
|
static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)
|
||||||
|
@ -125,10 +118,5 @@ static inline void drm_iommu_detach_device(struct drm_device *drm_dev,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <drm/exynos_drm.h>
|
#include <drm/exynos_drm.h>
|
||||||
#include "regs-rotator.h"
|
#include "regs-rotator.h"
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "exynos_drm_ipp.h"
|
#include "exynos_drm_ipp.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -263,7 +262,7 @@ static void rotator_unbind(struct device *dev, struct device *master,
|
||||||
struct exynos_drm_ipp *ipp = &rot->ipp;
|
struct exynos_drm_ipp *ipp = &rot->ipp;
|
||||||
|
|
||||||
exynos_drm_ipp_unregister(drm_dev, ipp);
|
exynos_drm_ipp_unregister(drm_dev, ipp);
|
||||||
drm_iommu_detach_device(rot->drm_dev, rot->dev);
|
exynos_drm_unregister_dma(rot->drm_dev, rot->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops rotator_component_ops = {
|
static const struct component_ops rotator_component_ops = {
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "regs-scaler.h"
|
#include "regs-scaler.h"
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
#include "exynos_drm_ipp.h"
|
#include "exynos_drm_ipp.h"
|
||||||
|
|
||||||
#define scaler_read(offset) readl(scaler->regs + (offset))
|
#define scaler_read(offset) readl(scaler->regs + (offset))
|
||||||
|
@ -473,7 +472,7 @@ static void scaler_unbind(struct device *dev, struct device *master,
|
||||||
struct exynos_drm_ipp *ipp = &scaler->ipp;
|
struct exynos_drm_ipp *ipp = &scaler->ipp;
|
||||||
|
|
||||||
exynos_drm_ipp_unregister(drm_dev, ipp);
|
exynos_drm_ipp_unregister(drm_dev, ipp);
|
||||||
drm_iommu_detach_device(scaler->drm_dev, scaler->dev);
|
exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops scaler_component_ops = {
|
static const struct component_ops scaler_component_ops = {
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include "exynos_drm_crtc.h"
|
#include "exynos_drm_crtc.h"
|
||||||
#include "exynos_drm_fb.h"
|
#include "exynos_drm_fb.h"
|
||||||
#include "exynos_drm_plane.h"
|
#include "exynos_drm_plane.h"
|
||||||
#include "exynos_drm_iommu.h"
|
|
||||||
|
|
||||||
#define MIXER_WIN_NR 3
|
#define MIXER_WIN_NR 3
|
||||||
#define VP_DEFAULT_WIN 2
|
#define VP_DEFAULT_WIN 2
|
||||||
|
@ -883,7 +882,7 @@ static int mixer_initialize(struct mixer_context *mixer_ctx,
|
||||||
|
|
||||||
static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
|
static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
|
||||||
{
|
{
|
||||||
drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
|
exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
|
static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
|
||||||
|
|
Loading…
Reference in a new issue