drm: rcar-du: Handle primary plane config through atomic plane ops
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 18 Feb 2015 13:47:27 +0000 (15:47 +0200)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tue, 3 Mar 2015 14:16:11 +0000 (16:16 +0200)
Use the new CRTC atomic transitional helpers drm_helper_crtc_mode_set()
and drm_helper_crtc_mode_set_base() to implement the CRTC .mode_set and
.mode_set_base operations. This delegates primary plane configuration to
the plane .atomic_update and .atomic_disable operations, removing
duplicate code from the CRTC implementation.

There is now no code path available to the driver in which to drop the
reference to the CRTC acquired in the .prepare() operation if an error
then occurs. The driver thus now leaks a reference if an error occurs
during mode set. So be it, this will be fixed in a further step of the
atomic update transition.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
drivers/gpu/drm/rcar-du/rcar_du_plane.c
drivers/gpu/drm/rcar-du/rcar_du_plane.h

index 3d862a894b1762674804ab6055e4540d5f2119b0..169558a3ab40ee296b93173fdbd51de6cfdf7b30 100644 (file)
@@ -105,7 +105,7 @@ static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
 
 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 {
-       const struct drm_display_mode *mode = &rcrtc->crtc.mode;
+       const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
        unsigned long mode_clock = mode->clock * 1000;
        unsigned long clk;
        u32 value;
@@ -368,7 +368,6 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
         * switching to atomic updates completely.
         */
        mutex_lock(&rcrtc->group->planes.lock);
-       rcrtc->plane->enabled = true;
        rcar_du_crtc_update_planes(crtc);
        mutex_unlock(&rcrtc->group->planes.lock);
 
@@ -412,11 +411,6 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
        rcar_du_crtc_wait_page_flip(rcrtc);
        drm_crtc_vblank_off(crtc);
 
-       mutex_lock(&rcrtc->group->planes.lock);
-       rcrtc->plane->enabled = false;
-       rcar_du_crtc_update_planes(crtc);
-       mutex_unlock(&rcrtc->group->planes.lock);
-
        /* Select switch sync mode. This stops display operation and configures
         * the HSYNC and VSYNC signals as inputs.
         */
@@ -492,58 +486,20 @@ static void rcar_du_crtc_mode_prepare(struct drm_crtc *crtc)
         */
        rcar_du_crtc_get(rcrtc);
 
-       /* Stop the CRTC and release the plane. Force the DPMS mode to off as a
-        * result.
-        */
+       /* Stop the CRTC, force the DPMS mode to off as a result. */
        rcar_du_crtc_stop(rcrtc);
-       rcar_du_plane_release(rcrtc->plane);
 
        rcrtc->dpms = DRM_MODE_DPMS_OFF;
+       rcrtc->outputs = 0;
 }
 
-static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
-                                struct drm_display_mode *mode,
-                                struct drm_display_mode *adjusted_mode,
-                                int x, int y,
-                                struct drm_framebuffer *old_fb)
+static void rcar_du_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
-       struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-       struct rcar_du_device *rcdu = rcrtc->group->dev;
-       const struct rcar_du_format_info *format;
-       int ret;
-
-       format = rcar_du_format_info(crtc->primary->fb->pixel_format);
-       if (format == NULL) {
-               dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n",
-                       crtc->primary->fb->pixel_format);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       ret = rcar_du_plane_reserve(rcrtc->plane, format);
-       if (ret < 0)
-               goto error;
-
-       rcrtc->plane->format = format;
-
-       rcrtc->plane->src_x = x;
-       rcrtc->plane->src_y = y;
-       rcrtc->plane->width = mode->hdisplay;
-       rcrtc->plane->height = mode->vdisplay;
-
-       rcar_du_plane_compute_base(rcrtc->plane, crtc->primary->fb);
-
-       rcrtc->outputs = 0;
-
-       return 0;
-
-error:
-       /* There's no rollback/abort operation to clean up in case of error. We
-        * thus need to release the reference to the CRTC acquired in prepare()
-        * here.
+       /* No-op. We should configure the display timings here, but as we're
+        * called with the CRTC disabled clocks might be off, and we thus can't
+        * access the hardware. Let's just configure everything when enabling
+        * the CRTC.
         */
-       rcar_du_crtc_put(rcrtc);
-       return ret;
 }
 
 static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
@@ -558,25 +514,9 @@ static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
        rcrtc->dpms = DRM_MODE_DPMS_ON;
 }
 
-static int rcar_du_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-                                     struct drm_framebuffer *old_fb)
-{
-       struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
-       rcrtc->plane->src_x = x;
-       rcrtc->plane->src_y = y;
-
-       rcar_du_crtc_update_base(rcrtc);
-
-       return 0;
-}
-
 static void rcar_du_crtc_disable(struct drm_crtc *crtc)
 {
-       struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
        rcar_du_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-       rcar_du_plane_release(rcrtc->plane);
 }
 
 static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc)
@@ -608,8 +548,9 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
        .mode_fixup = rcar_du_crtc_mode_fixup,
        .prepare = rcar_du_crtc_mode_prepare,
        .commit = rcar_du_crtc_mode_commit,
-       .mode_set = rcar_du_crtc_mode_set,
-       .mode_set_base = rcar_du_crtc_mode_set_base,
+       .mode_set = drm_helper_crtc_mode_set,
+       .mode_set_nofb = rcar_du_crtc_mode_set_nofb,
+       .mode_set_base = drm_helper_crtc_mode_set_base,
        .disable = rcar_du_crtc_disable,
        .atomic_begin = rcar_du_crtc_atomic_begin,
        .atomic_flush = rcar_du_crtc_atomic_flush,
index 03995c15bbe3fbd8f4f09c7287590439df633e58..d4682ac7db03518ac213eabc598943766755481c 100644 (file)
@@ -78,8 +78,8 @@ static int rcar_du_plane_reserve_check(struct rcar_du_plane *plane,
        return ret;
 }
 
-int rcar_du_plane_reserve(struct rcar_du_plane *plane,
-                         const struct rcar_du_format_info *format)
+static int rcar_du_plane_reserve(struct rcar_du_plane *plane,
+                                const struct rcar_du_format_info *format)
 {
        struct rcar_du_group *rgrp = plane->group;
        unsigned int i;
@@ -112,7 +112,7 @@ done:
        return ret;
 }
 
-void rcar_du_plane_release(struct rcar_du_plane *plane)
+static void rcar_du_plane_release(struct rcar_du_plane *plane)
 {
        struct rcar_du_group *rgrp = plane->group;
 
@@ -363,7 +363,6 @@ static void rcar_du_plane_disable(struct rcar_du_plane *rplane)
 
        mutex_lock(&rplane->group->planes.lock);
        rplane->enabled = false;
-       rcar_du_crtc_update_planes(rplane->crtc);
        mutex_unlock(&rplane->group->planes.lock);
 
        rcar_du_plane_release(rplane);
@@ -411,7 +410,6 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
 
        mutex_lock(&rplane->group->planes.lock);
        rplane->enabled = true;
-       rcar_du_crtc_update_planes(rplane->crtc);
        mutex_unlock(&rplane->group->planes.lock);
 }
 
index 813b3212392ac409ccc2b0dc22115cba26c38ac6..55d2f55faecef378918d9608909789794f19960e 100644 (file)
@@ -73,8 +73,5 @@ void rcar_du_plane_setup(struct rcar_du_plane *plane);
 void rcar_du_plane_update_base(struct rcar_du_plane *plane);
 void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
                                struct drm_framebuffer *fb);
-int rcar_du_plane_reserve(struct rcar_du_plane *plane,
-                         const struct rcar_du_format_info *format);
-void rcar_du_plane_release(struct rcar_du_plane *plane);
 
 #endif /* __RCAR_DU_PLANE_H__ */