diff options
author | Sean Paul <seanpaul@chromium.org> | 2014-02-19 21:02:55 +0900 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2014-03-24 00:36:31 +0900 |
commit | 080be03de296f68e8c6e13ab7545eae26db6359f (patch) | |
tree | 513d1e9e0d8bcda750c55c21f8bf120f2ea2cb8f /drivers/gpu/drm/exynos/exynos_drm_vidi.c | |
parent | 3f283d9375ad8fa97ac7a7b2d4f73425186d8810 (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_vidi.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 129 |
1 files changed, 60 insertions, 69 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 8d1fdc4e6bcb..f6f4438a40d9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -45,7 +45,7 @@ struct vidi_win_data { }; struct vidi_context { - struct exynos_drm_subdrv subdrv; + struct drm_device *drm_dev; struct drm_crtc *crtc; struct vidi_win_data win_data[WINDOWS_NR]; struct edid *raw_edid; @@ -58,6 +58,7 @@ struct vidi_context { bool direct_vblank; struct work_struct work; struct mutex lock; + int pipe; }; static const char fake_edid_info[] = { @@ -85,10 +86,9 @@ static const char fake_edid_info[] = { 0x00, 0x00, 0x00, 0x06 }; -static bool vidi_display_is_connected(struct device *dev) +static bool vidi_display_is_connected(struct exynos_drm_display *display) { - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = display->ctx; /* * connection request would come from user side @@ -97,11 +97,10 @@ static bool vidi_display_is_connected(struct device *dev) return ctx->connected ? true : false; } -static struct edid *vidi_get_edid(struct device *dev, +static struct edid *vidi_get_edid(struct exynos_drm_display *display, struct drm_connector *connector) { - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = display->ctx; struct edid *edid; /* @@ -122,14 +121,8 @@ static struct edid *vidi_get_edid(struct device *dev, return edid; } -static void *vidi_get_panel(struct device *dev) -{ - /* TODO. */ - - return NULL; -} - -static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode) +static int vidi_check_mode(struct exynos_drm_display *display, + struct drm_display_mode *mode) { /* TODO. */ @@ -137,13 +130,16 @@ static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode) } static struct exynos_drm_display_ops vidi_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_VIDI, .is_connected = vidi_display_is_connected, .get_edid = vidi_get_edid, - .get_panel = vidi_get_panel, .check_mode = vidi_check_mode, }; +static struct exynos_drm_display vidi_display = { + .type = EXYNOS_DISPLAY_TYPE_VIDI, + .ops = &vidi_display_ops, +}; + static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) { struct vidi_context *ctx = mgr->ctx; @@ -323,7 +319,38 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) /* TODO. */ } +static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, + struct drm_device *drm_dev, int pipe) +{ + struct vidi_context *ctx = mgr->ctx; + + DRM_ERROR("vidi initialize ct=%p dev=%p pipe=%d\n", ctx, drm_dev, pipe); + + ctx->drm_dev = drm_dev; + ctx->pipe = pipe; + + /* + * enable drm irq mode. + * - with irq_enabled = 1, we can use the vblank feature. + * + * P.S. note that we wouldn't use drm irq handler but + * just specific driver own one instead because + * drm framework supports only one irq handler. + */ + drm_dev->irq_enabled = 1; + + /* + * with vblank_disable_allowed = 1, vblank interrupt will be disabled + * by drm timer once a current process gives up ownership of + * vblank event.(after drm_vblank_put function is called) + */ + drm_dev->vblank_disable_allowed = 1; + + return 0; +} + static struct exynos_drm_manager_ops vidi_manager_ops = { + .initialize = vidi_mgr_initialize, .dpms = vidi_dpms, .commit = vidi_commit, .enable_vblank = vidi_enable_vblank, @@ -334,19 +361,16 @@ static struct exynos_drm_manager_ops vidi_manager_ops = { }; static struct exynos_drm_manager vidi_manager = { - .pipe = -1, - .ops = &vidi_manager_ops, - .display_ops = &vidi_display_ops, + .type = EXYNOS_DISPLAY_TYPE_VIDI, + .ops = &vidi_manager_ops, }; static void vidi_fake_vblank_handler(struct work_struct *work) { struct vidi_context *ctx = container_of(work, struct vidi_context, work); - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; - if (manager->pipe < 0) + if (ctx->pipe < 0) return; /* refresh rate is about 50Hz. */ @@ -355,7 +379,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) mutex_lock(&ctx->lock); if (ctx->direct_vblank) { - drm_handle_vblank(subdrv->drm_dev, manager->pipe); + drm_handle_vblank(ctx->drm_dev, ctx->pipe); ctx->direct_vblank = false; mutex_unlock(&ctx->lock); return; @@ -363,34 +387,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) mutex_unlock(&ctx->lock); - exynos_drm_crtc_finish_pageflip(subdrv->drm_dev, manager->pipe); -} - -static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) -{ - /* - * enable drm irq mode. - * - with irq_enabled = true, we can use the vblank feature. - * - * P.S. note that we wouldn't use drm irq handler but - * just specific driver own one instead because - * drm framework supports only one irq handler. - */ - drm_dev->irq_enabled = true; - - /* - * with vblank_disable_allowed = true, vblank interrupt will be disabled - * by drm timer once a current process gives up ownership of - * vblank event.(after drm_vblank_put function is called) - */ - drm_dev->vblank_disable_allowed = true; - - return 0; -} - -static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev) -{ - /* TODO. */ + exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); } static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) @@ -460,7 +457,7 @@ static int vidi_store_connection(struct device *dev, DRM_DEBUG_KMS("requested connection.\n"); - drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); + drm_helper_hpd_irq_event(ctx->drm_dev); return len; } @@ -473,8 +470,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, { struct vidi_context *ctx = NULL; struct drm_encoder *encoder; - struct exynos_drm_manager *manager; - struct exynos_drm_display_ops *display_ops; + struct exynos_drm_display *display; struct drm_exynos_vidi_connection *vidi = data; if (!vidi) { @@ -489,11 +485,10 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list, head) { - manager = exynos_drm_get_manager(encoder); - display_ops = manager->display_ops; + display = exynos_drm_get_display(encoder); - if (display_ops->type == EXYNOS_DISPLAY_TYPE_VIDI) { - ctx = manager->ctx; + if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) { + ctx = display->ctx; break; } } @@ -532,7 +527,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, } ctx->connected = vidi->connection; - drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); + drm_helper_hpd_irq_event(ctx->drm_dev); return 0; } @@ -541,7 +536,6 @@ static int vidi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct vidi_context *ctx; - struct exynos_drm_subdrv *subdrv; int ret; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); @@ -553,12 +547,7 @@ static int vidi_probe(struct platform_device *pdev) INIT_WORK(&ctx->work, vidi_fake_vblank_handler); vidi_manager.ctx = ctx; - - subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &vidi_manager; - subdrv->probe = vidi_subdrv_probe; - subdrv->remove = vidi_subdrv_remove; + vidi_display.ctx = ctx; mutex_init(&ctx->lock); @@ -568,7 +557,8 @@ static int vidi_probe(struct platform_device *pdev) if (ret < 0) DRM_INFO("failed to create connection sysfs.\n"); - exynos_drm_subdrv_register(subdrv); + exynos_drm_manager_register(&vidi_manager); + exynos_drm_display_register(&vidi_display); return 0; } @@ -577,7 +567,8 @@ static int vidi_remove(struct platform_device *pdev) { struct vidi_context *ctx = platform_get_drvdata(pdev); - exynos_drm_subdrv_unregister(&ctx->subdrv); + exynos_drm_display_unregister(&vidi_display); + exynos_drm_manager_unregister(&vidi_manager); if (ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); |