Commit eb4d9796 authored by Marek Szyprowski's avatar Marek Szyprowski Committed by Inki Dae

drm/exynos: g2d: Convert to driver component API

Exynos G2D driver is the last client of the custom Exynos 'sub-driver'
framework. In the current state it doesn't really resolve any of the
issues it has been designed for, as Exynos DRM is already built only
as a single kernel module. Remove the custom 'sub-driver' framework and
simply use generic component framework also in G2D driver.
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 2d3bda70
...@@ -4,7 +4,7 @@ ...@@ -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_core.o exynos_drm_plane.o exynos_drm_gem.o exynos_drm_plane.o
exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
......
/* exynos_drm_core.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* Author:
* Inki Dae <inki.dae@samsung.com>
* Joonyoung Shim <jy0922.shim@samsung.com>
* Seung-Woo Kim <sw0312.kim@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <drm/drmP.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
static LIST_HEAD(exynos_drm_subdrv_list);
int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
{
if (!subdrv)
return -EINVAL;
list_add_tail(&subdrv->list, &exynos_drm_subdrv_list);
return 0;
}
int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
{
if (!subdrv)
return -EINVAL;
list_del(&subdrv->list);
return 0;
}
int exynos_drm_device_subdrv_probe(struct drm_device *dev)
{
struct exynos_drm_subdrv *subdrv, *n;
int err;
if (!dev)
return -EINVAL;
list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
if (subdrv->probe) {
subdrv->drm_dev = dev;
/*
* this probe callback would be called by sub driver
* after setting of all resources to this sub driver,
* such as clock, irq and register map are done.
*/
err = subdrv->probe(dev, subdrv->dev);
if (err) {
DRM_DEBUG("exynos drm subdrv probe failed.\n");
list_del(&subdrv->list);
continue;
}
}
}
return 0;
}
int exynos_drm_device_subdrv_remove(struct drm_device *dev)
{
struct exynos_drm_subdrv *subdrv;
if (!dev) {
WARN(1, "Unexpected drm device unregister!\n");
return -EINVAL;
}
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->remove)
subdrv->remove(dev, subdrv->dev);
}
return 0;
}
int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
{
struct exynos_drm_subdrv *subdrv;
int ret;
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->open) {
ret = subdrv->open(dev, subdrv->dev, file);
if (ret)
goto err;
}
}
return 0;
err:
list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->close)
subdrv->close(dev, subdrv->dev, file);
}
return ret;
}
void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
{
struct exynos_drm_subdrv *subdrv;
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
if (subdrv->close)
subdrv->close(dev, subdrv->dev, file);
}
}
...@@ -55,8 +55,7 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) ...@@ -55,8 +55,7 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
return -ENOMEM; return -ENOMEM;
file->driver_priv = file_priv; file->driver_priv = file_priv;
ret = g2d_open(dev, file);
ret = exynos_drm_subdrv_open(dev, file);
if (ret) if (ret)
goto err_file_priv_free; goto err_file_priv_free;
...@@ -70,7 +69,7 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) ...@@ -70,7 +69,7 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
{ {
exynos_drm_subdrv_close(dev, file); g2d_close(dev, file);
kfree(file->driver_priv); kfree(file->driver_priv);
file->driver_priv = NULL; file->driver_priv = NULL;
} }
...@@ -240,6 +239,7 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = { ...@@ -240,6 +239,7 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
DRM_COMPONENT_DRIVER | DRM_VIRTUAL_DEVICE DRM_COMPONENT_DRIVER | DRM_VIRTUAL_DEVICE
}, { }, {
DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D), DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D),
DRM_COMPONENT_DRIVER
}, { }, {
DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC), DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC),
DRM_COMPONENT_DRIVER | DRM_FIMC_DEVICE, DRM_COMPONENT_DRIVER | DRM_FIMC_DEVICE,
...@@ -376,11 +376,6 @@ static int exynos_drm_bind(struct device *dev) ...@@ -376,11 +376,6 @@ static int exynos_drm_bind(struct device *dev)
if (ret) if (ret)
goto err_unbind_all; goto err_unbind_all;
/* Probe non kms sub drivers and virtual display driver. */
ret = exynos_drm_device_subdrv_probe(drm);
if (ret)
goto err_unbind_all;
drm_mode_config_reset(drm); drm_mode_config_reset(drm);
/* /*
...@@ -411,7 +406,6 @@ static int exynos_drm_bind(struct device *dev) ...@@ -411,7 +406,6 @@ static int exynos_drm_bind(struct device *dev)
exynos_drm_fbdev_fini(drm); exynos_drm_fbdev_fini(drm);
err_cleanup_poll: err_cleanup_poll:
drm_kms_helper_poll_fini(drm); drm_kms_helper_poll_fini(drm);
exynos_drm_device_subdrv_remove(drm);
err_unbind_all: err_unbind_all:
component_unbind_all(drm->dev, drm); component_unbind_all(drm->dev, drm);
err_mode_config_cleanup: err_mode_config_cleanup:
...@@ -431,8 +425,6 @@ static void exynos_drm_unbind(struct device *dev) ...@@ -431,8 +425,6 @@ static void exynos_drm_unbind(struct device *dev)
drm_dev_unregister(drm); drm_dev_unregister(drm);
exynos_drm_device_subdrv_remove(drm);
exynos_drm_fbdev_fini(drm); exynos_drm_fbdev_fini(drm);
drm_kms_helper_poll_fini(drm); drm_kms_helper_poll_fini(drm);
......
...@@ -179,17 +179,13 @@ static inline void exynos_drm_pipe_clk_enable(struct exynos_drm_crtc *crtc, ...@@ -179,17 +179,13 @@ static inline void exynos_drm_pipe_clk_enable(struct exynos_drm_crtc *crtc,
crtc->pipe_clk->enable(crtc->pipe_clk, enable); crtc->pipe_clk->enable(crtc->pipe_clk, enable);
} }
struct exynos_drm_g2d_private { struct drm_exynos_file_private {
struct device *dev; /* for g2d api */
struct list_head inuse_cmdlist; struct list_head inuse_cmdlist;
struct list_head event_list; struct list_head event_list;
struct list_head userptr_list; struct list_head userptr_list;
}; };
struct drm_exynos_file_private {
struct exynos_drm_g2d_private *g2d_priv;
};
/* /*
* Exynos drm private structure. * Exynos drm private structure.
* *
...@@ -201,6 +197,7 @@ struct exynos_drm_private { ...@@ -201,6 +197,7 @@ struct exynos_drm_private {
struct drm_fb_helper *fb_helper; struct drm_fb_helper *fb_helper;
struct drm_atomic_state *suspend_state; struct drm_atomic_state *suspend_state;
struct device *g2d_dev;
struct device *dma_dev; struct device *dma_dev;
void *mapping; void *mapping;
...@@ -217,44 +214,6 @@ static inline struct device *to_dma_dev(struct drm_device *dev) ...@@ -217,44 +214,6 @@ static inline struct device *to_dma_dev(struct drm_device *dev)
return priv->dma_dev; return priv->dma_dev;
} }
/*
* Exynos drm sub driver structure.
*
* @list: sub driver has its own list object to register to exynos drm driver.
* @dev: pointer to device object for subdrv device driver.
* @drm_dev: pointer to drm_device and this pointer would be set
* when sub driver calls exynos_drm_subdrv_register().
* @probe: this callback would be called by exynos drm driver after
* subdrv is registered to it.
* @remove: this callback is used to release resources created
* by probe callback.
* @open: this would be called with drm device file open.
* @close: this would be called with drm device file close.
*/
struct exynos_drm_subdrv {
struct list_head list;
struct device *dev;
struct drm_device *drm_dev;
int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *drm_dev, struct device *dev);
int (*open)(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file);
void (*close)(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file);
};
/* This function would be called by non kms drivers such as g2d and ipp. */
int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv);
/* this function removes subdrv list from exynos drm driver */
int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv);
int exynos_drm_device_subdrv_probe(struct drm_device *dev);
int exynos_drm_device_subdrv_remove(struct drm_device *dev);
int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
#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);
int exynos_dpi_remove(struct drm_encoder *encoder); int exynos_dpi_remove(struct drm_encoder *encoder);
......
This diff is collapsed.
...@@ -14,6 +14,9 @@ extern int exynos_g2d_set_cmdlist_ioctl(struct drm_device *dev, void *data, ...@@ -14,6 +14,9 @@ extern int exynos_g2d_set_cmdlist_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data, extern int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int g2d_open(struct drm_device *drm_dev, struct drm_file *file);
extern void g2d_close(struct drm_device *drm_dev, struct drm_file *file);
#else #else
static inline int exynos_g2d_get_ver_ioctl(struct drm_device *dev, void *data, static inline int exynos_g2d_get_ver_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
...@@ -33,4 +36,12 @@ static inline int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data, ...@@ -33,4 +36,12 @@ static inline int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data,
{ {
return -ENODEV; return -ENODEV;
} }
int g2d_open(struct drm_device *drm_dev, struct drm_file *file)
{
return 0;
}
void g2d_close(struct drm_device *drm_dev, struct drm_file *file)
{ }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment