drm/exynos: use drm core to handle page-flip event
authorAndrzej Hajda <a.hajda@samsung.com>
Fri, 23 Sep 2016 13:21:38 +0000 (15:21 +0200)
committerInki Dae <daeinki@gmail.com>
Fri, 30 Sep 2016 15:39:37 +0000 (00:39 +0900)
Exynos DRM framework handled page-flip event with custom code.
The patch replaces it with drm-core vblank queue.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_mixer.c

index ac21b40008358efc49f357deceb09a58cb138356..6ca1f3117fe8d524fbb4dfed89692c527c5bd41c 100644 (file)
@@ -551,7 +551,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 {
        struct decon_context *ctx = dev_id;
        u32 val;
-       int win;
 
        if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
                goto out;
@@ -560,16 +559,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
        val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
 
        if (val) {
-               for (win = ctx->first_win; win < WINDOWS_NR ; win++) {
-                       struct exynos_drm_plane *plane = &ctx->planes[win];
-
-                       if (!plane->pending_fb)
-                               continue;
-
-                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
-               }
-
-               /* clear */
                writel(val, ctx->addr + DECON_VIDINTCON1);
                drm_crtc_handle_vblank(&ctx->crtc->base);
        }
index 7f9901b7777b36786380c447c784418f4d7e3b07..f4d5a2133777d8cd40df1d7a346c301cf7c5313c 100644 (file)
@@ -603,7 +603,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 {
        struct decon_context *ctx = (struct decon_context *)dev_id;
        u32 val, clear_bit;
-       int win;
 
        val = readl(ctx->regs + VIDINTCON1);
 
@@ -617,14 +616,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 
        if (!ctx->i80_if) {
                drm_crtc_handle_vblank(&ctx->crtc->base);
-               for (win = 0 ; win < WINDOWS_NR ; win++) {
-                       struct exynos_drm_plane *plane = &ctx->planes[win];
-
-                       if (!plane->pending_fb)
-                               continue;
-
-                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
-               }
 
                /* set wait vsync event to zero and wake up queue. */
                if (atomic_read(&ctx->wait_vsync_event)) {
index 5b6845bc18fc7fc7f65528879e751e974fc57c61..2530bf57716a93a800fca4b1a1608052cfe7db39 100644 (file)
@@ -69,8 +69,6 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc,
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
-       exynos_crtc->event = crtc->state->event;
-
        if (exynos_crtc->ops->atomic_begin)
                exynos_crtc->ops->atomic_begin(exynos_crtc);
 }
@@ -79,9 +77,24 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
                                     struct drm_crtc_state *old_crtc_state)
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+       struct drm_pending_vblank_event *event;
+       unsigned long flags;
 
        if (exynos_crtc->ops->atomic_flush)
                exynos_crtc->ops->atomic_flush(exynos_crtc);
+
+       event = crtc->state->event;
+       if (event) {
+               crtc->state->event = NULL;
+
+               spin_lock_irqsave(&crtc->dev->event_lock, flags);
+               if (drm_crtc_vblank_get(crtc) == 0)
+                       drm_crtc_arm_vblank_event(crtc, event);
+               else
+                       drm_crtc_send_vblank_event(crtc, event);
+               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+       }
+
 }
 
 static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
@@ -173,22 +186,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe)
                exynos_crtc->ops->disable_vblank(exynos_crtc);
 }
 
-void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
-                               struct exynos_drm_plane *exynos_plane)
-{
-       struct drm_crtc *crtc = &exynos_crtc->base;
-       unsigned long flags;
-
-       exynos_plane->pending_fb = NULL;
-
-       spin_lock_irqsave(&crtc->dev->event_lock, flags);
-       if (exynos_crtc->event)
-               drm_crtc_send_vblank_event(crtc, exynos_crtc->event);
-
-       exynos_crtc->event = NULL;
-       spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-}
-
 int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
                                       enum exynos_drm_output_type out_type)
 {
@@ -216,18 +213,19 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
 void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
                                        struct drm_file *file)
 {
-       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
        struct drm_pending_vblank_event *e;
        unsigned long flags;
 
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
-       e = exynos_crtc->event;
+       e = crtc->state->event;
        if (e && e->base.file_priv == file)
-               exynos_crtc->event = NULL;
+               crtc->state->event = NULL;
+       else
+               e = NULL;
 
        spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 
-       if (e && e->base.file_priv == file)
+       if (e)
                drm_event_cancel_free(crtc->dev, &e->base);
 }
index cee3a4c761060e4a9e2447b8006c45259fc5daf6..d215149e737b1d19128740f861fb9d83bb7f3606 100644 (file)
@@ -86,7 +86,6 @@ struct exynos_drm_plane {
        struct drm_plane base;
        const struct exynos_drm_plane_config *config;
        unsigned int index;
-       struct drm_framebuffer *pending_fb;
 };
 
 #define EXYNOS_DRM_PLANE_CAP_DOUBLE    (1 << 0)
@@ -172,7 +171,6 @@ struct exynos_drm_crtc {
        struct drm_crtc                 base;
        enum exynos_drm_output_type     type;
        unsigned int                    pipe;
-       struct drm_pending_vblank_event *event;
        const struct exynos_drm_crtc_ops        *ops;
        void                            *ctx;
        struct exynos_drm_clk           *pipe_clk;
index 27efe3087d188debb435c8c427b9775fdfea2b8f..e2e405170d35762a209ae9cb13d58fde87e310e7 100644 (file)
@@ -962,8 +962,7 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
 {
        struct fimd_context *ctx = (struct fimd_context *)dev_id;
-       u32 val, clear_bit, start, start_s;
-       int win;
+       u32 val, clear_bit;
 
        val = readl(ctx->regs + VIDINTCON1);
 
@@ -978,18 +977,6 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
        if (!ctx->i80_if)
                drm_crtc_handle_vblank(&ctx->crtc->base);
 
-       for (win = 0 ; win < WINDOWS_NR ; win++) {
-               struct exynos_drm_plane *plane = &ctx->planes[win];
-
-               if (!plane->pending_fb)
-                       continue;
-
-               start = readl(ctx->regs + VIDWx_BUF_START(win, 0));
-               start_s = readl(ctx->regs + VIDWx_BUF_START_S(win, 0));
-               if (start == start_s)
-                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
-       }
-
        if (ctx->i80_if) {
                /* Exits triggering mode */
                atomic_set(&ctx->triggering, 0);
index 7f32419b25ea3809477139851b6826bc9e375be8..c2f17f30afab2db811eed293d05662e90727d5d3 100644 (file)
@@ -238,7 +238,6 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
                return;
 
        plane->crtc = state->crtc;
-       exynos_plane->pending_fb = state->fb;
 
        if (exynos_crtc->ops->update_plane)
                exynos_crtc->ops->update_plane(exynos_crtc, exynos_plane);
index a91dad65e9080fe5774f7931351d4f42f82a9524..57fe514d5c5bf9adc9f423d9f46a51e25aedfa46 100644 (file)
@@ -175,7 +175,6 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
 static void vidi_fake_vblank_timer(unsigned long arg)
 {
        struct vidi_context *ctx = (void *)arg;
-       int win;
 
        if (ctx->pipe < 0)
                return;
@@ -183,15 +182,6 @@ static void vidi_fake_vblank_timer(unsigned long arg)
        if (drm_crtc_handle_vblank(&ctx->crtc->base))
                mod_timer(&ctx->timer,
                        jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1);
-
-       for (win = 0 ; win < WINDOWS_NR ; win++) {
-               struct exynos_drm_plane *plane = &ctx->planes[win];
-
-               if (!plane->pending_fb)
-                       continue;
-
-               exynos_drm_crtc_finish_update(ctx->crtc, plane);
-       }
 }
 
 static ssize_t vidi_show_connection(struct device *dev,
index bea3cbd39a2531ad9a91191e2a060cbb44faac75..edb20a34c66c06f1533513f02ed9eaceedeed63b 100644 (file)
@@ -754,7 +754,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
        struct mixer_context *ctx = arg;
        struct mixer_resources *res = &ctx->mixer_res;
        u32 val, base, shadow;
-       int win;
 
        spin_lock(&res->reg_slock);
 
@@ -781,14 +780,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
                }
 
                drm_crtc_handle_vblank(&ctx->crtc->base);
-               for (win = 0 ; win < MIXER_WIN_NR ; win++) {
-                       struct exynos_drm_plane *plane = &ctx->planes[win];
-
-                       if (!plane->pending_fb)
-                               continue;
-
-                       exynos_drm_crtc_finish_update(ctx->crtc, plane);
-               }
        }
 
 out: