summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2014-02-19 21:02:55 +0900
committerInki Dae <daeinki@gmail.com>2014-03-24 00:36:31 +0900
commit080be03de296f68e8c6e13ab7545eae26db6359f (patch)
tree513d1e9e0d8bcda750c55c21f8bf120f2ea2cb8f /drivers/gpu/drm/exynos/exynos_drm_hdmi.c
parent3f283d9375ad8fa97ac7a7b2d4f73425186d8810 (diff)
drm/exynos: Split manager/display/subdrv
This patch splits display and manager from subdrv. The result is that crtc functions can directly call into manager callbacks and encoder functions can directly call into display callbacks. This will allow us to remove the exynos_drm_hdmi shim and support mixer/hdmi & fimd/dp with common code. Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_hdmi.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c211
1 files changed, 89 insertions, 122 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index f9a9324a8d21..b0b09b298ac3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -23,11 +23,6 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_hdmi.h"
-#define to_context(dev) platform_get_drvdata(to_platform_device(dev))
-#define to_subdrv(dev) to_context(dev)
-#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\
- struct drm_hdmi_context, subdrv);
-
/* platform device pointer for common drm hdmi device. */
static struct platform_device *exynos_drm_hdmi_pdev;
@@ -41,7 +36,6 @@ static struct exynos_hdmi_ops *hdmi_ops;
static struct exynos_mixer_ops *mixer_ops;
struct drm_hdmi_context {
- struct exynos_drm_subdrv subdrv;
struct exynos_drm_hdmi_context *hdmi_ctx;
struct exynos_drm_hdmi_context *mixer_ctx;
@@ -97,10 +91,10 @@ void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
mixer_ops = ops;
}
-static int drm_hdmi_display_initialize(struct device *dev,
+static int drm_hdmi_display_initialize(struct exynos_drm_display *display,
struct drm_device *drm_dev)
{
- struct drm_hdmi_context *ctx = to_context(dev);
+ struct drm_hdmi_context *ctx = display->ctx;
if (hdmi_ops && hdmi_ops->initialize)
return hdmi_ops->initialize(ctx->hdmi_ctx->ctx, drm_dev);
@@ -109,9 +103,9 @@ static int drm_hdmi_display_initialize(struct device *dev,
}
-static bool drm_hdmi_is_connected(struct device *dev)
+static bool drm_hdmi_is_connected(struct exynos_drm_display *display)
{
- struct drm_hdmi_context *ctx = to_context(dev);
+ struct drm_hdmi_context *ctx = display->ctx;
if (hdmi_ops && hdmi_ops->is_connected)
return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
@@ -119,10 +113,10 @@ static bool drm_hdmi_is_connected(struct device *dev)
return false;
}
-static struct edid *drm_hdmi_get_edid(struct device *dev,
+static struct edid *drm_hdmi_get_edid(struct exynos_drm_display *display,
struct drm_connector *connector)
{
- struct drm_hdmi_context *ctx = to_context(dev);
+ struct drm_hdmi_context *ctx = display->ctx;
if (hdmi_ops && hdmi_ops->get_edid)
return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector);
@@ -151,68 +145,28 @@ static int drm_hdmi_check_mode_ctx(struct drm_hdmi_context *ctx,
return 0;
}
-static int drm_hdmi_check_mode(struct device *dev,
+static int drm_hdmi_check_mode(struct exynos_drm_display *display,
struct drm_display_mode *mode)
{
- struct drm_hdmi_context *ctx = to_context(dev);
+ struct drm_hdmi_context *ctx = display->ctx;
return drm_hdmi_check_mode_ctx(ctx, mode);
}
-static int drm_hdmi_display_dpms(struct device *dev, int mode)
+static void drm_hdmi_display_dpms(struct exynos_drm_display *display, int mode)
{
- struct drm_hdmi_context *ctx = to_context(dev);
+ struct drm_hdmi_context *ctx = display->ctx;
if (hdmi_ops && hdmi_ops->dpms)
hdmi_ops->dpms(ctx->hdmi_ctx->ctx, mode);
-
- return 0;
}
-static struct exynos_drm_display_ops drm_hdmi_display_ops = {
- .type = EXYNOS_DISPLAY_TYPE_HDMI,
- .initialize = drm_hdmi_display_initialize,
- .is_connected = drm_hdmi_is_connected,
- .get_edid = drm_hdmi_get_edid,
- .check_mode = drm_hdmi_check_mode,
- .dpms = drm_hdmi_display_dpms,
-};
-
-static int drm_hdmi_enable_vblank(struct exynos_drm_manager *mgr)
-{
- struct drm_hdmi_context *ctx = mgr->ctx;
- struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
- struct exynos_drm_manager *manager = subdrv->manager;
-
- if (mixer_ops && mixer_ops->enable_vblank)
- return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
- manager->pipe);
-
- return 0;
-}
-
-static void drm_hdmi_disable_vblank(struct exynos_drm_manager *mgr)
-{
- struct drm_hdmi_context *ctx = mgr->ctx;
-
- if (mixer_ops && mixer_ops->disable_vblank)
- return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
-}
-
-static void drm_hdmi_wait_for_vblank(struct exynos_drm_manager *mgr)
-{
- struct drm_hdmi_context *ctx = mgr->ctx;
-
- if (mixer_ops && mixer_ops->wait_for_vblank)
- mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
-}
-
-static void drm_hdmi_mode_fixup(struct exynos_drm_manager *mgr,
+static void drm_hdmi_mode_fixup(struct exynos_drm_display *display,
struct drm_connector *connector,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_hdmi_context *ctx = mgr->ctx;
+ struct drm_hdmi_context *ctx = display->ctx;
struct drm_display_mode *m;
int mode_ok;
@@ -252,23 +206,66 @@ static void drm_hdmi_mode_fixup(struct exynos_drm_manager *mgr,
}
}
-static void drm_hdmi_mode_set(struct exynos_drm_manager *mgr, void *mode)
+static void drm_hdmi_mode_set(struct exynos_drm_display *display,
+ struct drm_display_mode *mode)
{
- struct drm_hdmi_context *ctx = mgr->ctx;
+ struct drm_hdmi_context *ctx = display->ctx;
if (hdmi_ops && hdmi_ops->mode_set)
hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
}
-static void drm_hdmi_get_max_resol(struct exynos_drm_manager *mgr,
+static void drm_hdmi_get_max_resol(struct exynos_drm_display *display,
unsigned int *width, unsigned int *height)
{
- struct drm_hdmi_context *ctx = mgr->ctx;
+ struct drm_hdmi_context *ctx = display->ctx;
if (hdmi_ops && hdmi_ops->get_max_resol)
hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
}
+static struct exynos_drm_display_ops drm_hdmi_display_ops = {
+ .initialize = drm_hdmi_display_initialize,
+ .is_connected = drm_hdmi_is_connected,
+ .get_edid = drm_hdmi_get_edid,
+ .check_mode = drm_hdmi_check_mode,
+ .dpms = drm_hdmi_display_dpms,
+ .mode_fixup = drm_hdmi_mode_fixup,
+ .mode_set = drm_hdmi_mode_set,
+ .get_max_resol = drm_hdmi_get_max_resol,
+};
+
+static struct exynos_drm_display hdmi_display = {
+ .type = EXYNOS_DISPLAY_TYPE_HDMI,
+ .ops = &drm_hdmi_display_ops,
+};
+
+static int drm_hdmi_enable_vblank(struct exynos_drm_manager *mgr)
+{
+ struct drm_hdmi_context *ctx = mgr->ctx;
+
+ if (mixer_ops && mixer_ops->enable_vblank)
+ return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, mgr->pipe);
+
+ return 0;
+}
+
+static void drm_hdmi_disable_vblank(struct exynos_drm_manager *mgr)
+{
+ struct drm_hdmi_context *ctx = mgr->ctx;
+
+ if (mixer_ops && mixer_ops->disable_vblank)
+ return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
+}
+
+static void drm_hdmi_wait_for_vblank(struct exynos_drm_manager *mgr)
+{
+ struct drm_hdmi_context *ctx = mgr->ctx;
+
+ if (mixer_ops && mixer_ops->wait_for_vblank)
+ mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
+}
+
static void drm_hdmi_commit(struct exynos_drm_manager *mgr)
{
struct drm_hdmi_context *ctx = mgr->ctx;
@@ -277,11 +274,25 @@ static void drm_hdmi_commit(struct exynos_drm_manager *mgr)
hdmi_ops->commit(ctx->hdmi_ctx->ctx);
}
-static int drm_hdmi_mgr_initialize(struct exynos_drm_manager *mgr, struct drm_device *drm_dev)
+static int drm_hdmi_mgr_initialize(struct exynos_drm_manager *mgr,
+ struct drm_device *drm_dev, int pipe)
{
struct drm_hdmi_context *ctx = mgr->ctx;
int ret = 0;
+ if (!hdmi_ctx) {
+ DRM_ERROR("hdmi context not initialized.\n");
+ return -EFAULT;
+ }
+
+ if (!mixer_ctx) {
+ DRM_ERROR("mixer context not initialized.\n");
+ return -EFAULT;
+ }
+
+ ctx->hdmi_ctx = hdmi_ctx;
+ ctx->mixer_ctx = mixer_ctx;
+
if (mixer_ops && mixer_ops->initialize)
ret = mixer_ops->initialize(ctx->mixer_ctx->ctx, drm_dev);
@@ -291,6 +302,14 @@ static int drm_hdmi_mgr_initialize(struct exynos_drm_manager *mgr, struct drm_de
return ret;
}
+static void drm_hdmi_mgr_remove(struct exynos_drm_manager *mgr)
+{
+ struct drm_hdmi_context *ctx = mgr->ctx;
+
+ if (mixer_ops->iommu_on)
+ mixer_ops->iommu_on(ctx->mixer_ctx->ctx, false);
+}
+
static void drm_hdmi_dpms(struct exynos_drm_manager *mgr, int mode)
{
struct drm_hdmi_context *ctx = mgr->ctx;
@@ -345,13 +364,11 @@ static void drm_mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
static struct exynos_drm_manager_ops drm_hdmi_manager_ops = {
.initialize = drm_hdmi_mgr_initialize,
+ .remove = drm_hdmi_mgr_remove,
.dpms = drm_hdmi_dpms,
.enable_vblank = drm_hdmi_enable_vblank,
.disable_vblank = drm_hdmi_disable_vblank,
.wait_for_vblank = drm_hdmi_wait_for_vblank,
- .mode_fixup = drm_hdmi_mode_fixup,
- .mode_set = drm_hdmi_mode_set,
- .get_max_resol = drm_hdmi_get_max_resol,
.commit = drm_hdmi_commit,
.win_mode_set = drm_mixer_win_mode_set,
.win_commit = drm_mixer_win_commit,
@@ -359,55 +376,13 @@ static struct exynos_drm_manager_ops drm_hdmi_manager_ops = {
};
static struct exynos_drm_manager hdmi_manager = {
- .pipe = -1,
+ .type = EXYNOS_DISPLAY_TYPE_HDMI,
.ops = &drm_hdmi_manager_ops,
- .display_ops = &drm_hdmi_display_ops,
};
-static int hdmi_subdrv_probe(struct drm_device *drm_dev,
- struct device *dev)
-{
- struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
- struct drm_hdmi_context *ctx;
-
- if (!hdmi_ctx) {
- DRM_ERROR("hdmi context not initialized.\n");
- return -EFAULT;
- }
-
- if (!mixer_ctx) {
- DRM_ERROR("mixer context not initialized.\n");
- return -EFAULT;
- }
-
- ctx = get_ctx_from_subdrv(subdrv);
-
- if (!ctx) {
- DRM_ERROR("no drm hdmi context.\n");
- return -EFAULT;
- }
-
- ctx->hdmi_ctx = hdmi_ctx;
- ctx->mixer_ctx = mixer_ctx;
-
- return 0;
-}
-
-static void hdmi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
-{
- struct drm_hdmi_context *ctx;
- struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
-
- ctx = get_ctx_from_subdrv(subdrv);
-
- if (mixer_ops->iommu_on)
- mixer_ops->iommu_on(ctx->mixer_ctx->ctx, false);
-}
-
static int exynos_drm_hdmi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct exynos_drm_subdrv *subdrv;
struct drm_hdmi_context *ctx;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
@@ -415,26 +390,18 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev)
return -ENOMEM;
hdmi_manager.ctx = ctx;
+ hdmi_display.ctx = ctx;
- subdrv = &ctx->subdrv;
-
- subdrv->dev = dev;
- subdrv->manager = &hdmi_manager;
- subdrv->probe = hdmi_subdrv_probe;
- subdrv->remove = hdmi_subdrv_remove;
-
- platform_set_drvdata(pdev, subdrv);
-
- exynos_drm_subdrv_register(subdrv);
+ exynos_drm_manager_register(&hdmi_manager);
+ exynos_drm_display_register(&hdmi_display);
return 0;
}
static int exynos_drm_hdmi_remove(struct platform_device *pdev)
{
- struct drm_hdmi_context *ctx = platform_get_drvdata(pdev);
-
- exynos_drm_subdrv_unregister(&ctx->subdrv);
+ exynos_drm_display_unregister(&hdmi_display);
+ exynos_drm_manager_unregister(&hdmi_manager);
return 0;
}