From 9d5ab6a0ff7bb9565e8e1bcce5648964b6434470 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 1 Jun 2015 12:04:48 -0300 Subject: [PATCH] drm/exynos: atomic phase 3: convert page flips PageFlips now use the atomic helper to work through the atomic modesetting API. Async page flips are not supported yet. v2: Add .atomic_begin() step to handle the vblank part we removed from exynos page_flip code. Signed-off-by: Gustavo Padovan Reviewed-by: Joonyoung Shim Tested-by: Tobias Jakobi Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 79 +++++------------------- drivers/gpu/drm/exynos/exynos_drm_fb.c | 9 ++- 2 files changed, 25 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index dd1ee7f383cd..a13779915cde 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -101,75 +101,30 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc) } } +static void exynos_crtc_atomic_begin(struct drm_crtc *crtc) +{ + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); + + if (crtc->state->event) { + WARN_ON(drm_crtc_vblank_get(crtc) != 0); + exynos_crtc->event = crtc->state->event; + } +} + +static void exynos_crtc_atomic_flush(struct drm_crtc *crtc) +{ +} + static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { .dpms = exynos_drm_crtc_dpms, .commit = exynos_drm_crtc_commit, .mode_fixup = exynos_drm_crtc_mode_fixup, .mode_set_nofb = exynos_drm_crtc_mode_set_nofb, .disable = exynos_drm_crtc_disable, + .atomic_begin = exynos_crtc_atomic_begin, + .atomic_flush = exynos_crtc_atomic_flush, }; -static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags) -{ - struct drm_device *dev = crtc->dev; - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - unsigned int crtc_w, crtc_h; - int ret; - - /* when the page flip is requested, crtc's dpms should be on */ - if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { - DRM_ERROR("failed page flip request.\n"); - return -EINVAL; - } - - if (!event) - return -EINVAL; - - spin_lock_irq(&dev->event_lock); - if (exynos_crtc->event) { - ret = -EBUSY; - goto out; - } - - ret = exynos_check_plane(crtc->primary, fb); - if (ret) - goto out; - - ret = drm_vblank_get(dev, exynos_crtc->pipe); - if (ret) { - DRM_DEBUG("failed to acquire vblank counter\n"); - goto out; - } - - exynos_crtc->event = event; - spin_unlock_irq(&dev->event_lock); - - /* - * the pipe from user always is 0 so we can set pipe number - * of current owner to event. - */ - event->pipe = exynos_crtc->pipe; - - crtc->primary->fb = fb; - crtc_w = fb->width - crtc->x; - crtc_h = fb->height - crtc->y; - exynos_update_plane(crtc->primary, crtc, fb, 0, 0, - crtc_w, crtc_h, crtc->x << 16, crtc->y << 16, - crtc_w << 16, crtc_h << 16); - - if (crtc->primary->state) - drm_atomic_set_fb_for_plane(crtc->primary->state, fb); - - return 0; - -out: - spin_unlock_irq(&dev->event_lock); - return ret; -} - static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); @@ -183,7 +138,7 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) static struct drm_crtc_funcs exynos_crtc_funcs = { .set_config = drm_atomic_helper_set_config, - .page_flip = exynos_drm_crtc_page_flip, + .page_flip = drm_atomic_helper_page_flip, .destroy = exynos_drm_crtc_destroy, .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 19c06429fc45..05d229c1629a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -266,11 +266,18 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev) exynos_drm_fbdev_init(dev); } +static int exynos_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool async) +{ + return drm_atomic_helper_commit(dev, state, false); +} + static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { .fb_create = exynos_user_fb_create, .output_poll_changed = exynos_drm_output_poll_changed, .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, + .atomic_commit = exynos_atomic_commit, }; void exynos_drm_mode_config_init(struct drm_device *dev)