drm: rcar-du: Don't initialize event->pipe field
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / rcar-du / rcar_du_crtc.c
index faa46ed23a62329a2900f6329fdb753ca4075b17..7d0b8ef9bea21ca04a7fc678f3913dc1768615fd 100644 (file)
@@ -198,9 +198,14 @@ static unsigned int plane_zpos(struct rcar_du_plane *plane)
        return to_rcar_du_plane_state(plane->plane.state)->zpos;
 }
 
-static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
+static const struct rcar_du_format_info *
+plane_format(struct rcar_du_plane *plane)
+{
+       return to_rcar_du_plane_state(plane->plane.state)->format;
+}
+
+static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
 {
-       struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
        struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
        unsigned int num_planes = 0;
        unsigned int prio = 0;
@@ -212,7 +217,7 @@ static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
                struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
                unsigned int j;
 
-               if (plane->crtc != &rcrtc->crtc || !plane->enabled)
+               if (plane->plane.state->crtc != &rcrtc->crtc)
                        continue;
 
                /* Insert the plane in the sorted planes array. */
@@ -223,18 +228,19 @@ static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
                }
 
                planes[j] = plane;
-               prio += plane->format->planes * 4;
+               prio += plane_format(plane)->planes * 4;
        }
 
        for (i = 0; i < num_planes; ++i) {
                struct rcar_du_plane *plane = planes[i];
-               unsigned int index = plane->hwindex;
+               struct drm_plane_state *state = plane->plane.state;
+               unsigned int index = to_rcar_du_plane_state(state)->hwindex;
 
                prio -= 4;
                dspr |= (index + 1) << prio;
                dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
 
-               if (plane->format->planes == 2) {
+               if (plane_format(plane)->planes == 2) {
                        index = (index + 1) % 8;
 
                        prio -= 4;
@@ -247,8 +253,6 @@ static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
         * with superposition controller 2.
         */
        if (rcrtc->index % 2) {
-               u32 value = rcar_du_group_read(rcrtc->group, DPTSR);
-
                /* The DPTSR register is updated when the display controller is
                 * stopped. We thus need to restart the DU. Once again, sorry
                 * for the flicker. One way to mitigate the issue would be to
@@ -256,11 +260,13 @@ static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
                 * split, or through a module parameter). Flicker would then
                 * occur only if we need to break the pre-association.
                 */
-               if (value != dptsr) {
+               mutex_lock(&rcrtc->group->lock);
+               if (rcar_du_group_read(rcrtc->group, DPTSR) != dptsr) {
                        rcar_du_group_write(rcrtc->group, DPTSR, dptsr);
                        if (rcrtc->group->used_crtcs)
                                rcar_du_group_restart(rcrtc->group);
                }
+               mutex_unlock(&rcrtc->group->lock);
        }
 
        rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
@@ -348,14 +354,10 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
 {
        struct drm_crtc *crtc = &rcrtc->crtc;
        bool interlaced;
-       unsigned int i;
 
        if (rcrtc->started)
                return;
 
-       if (WARN_ON(rcrtc->plane->format == NULL))
-               return;
-
        /* Set display off and background to black */
        rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
        rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
@@ -364,26 +366,8 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
        rcar_du_crtc_set_display_timing(rcrtc);
        rcar_du_group_set_routing(rcrtc->group);
 
-       /* FIXME: Commit the planes state. This is required here as the CRTC can
-        * be started from the system resume handler, which don't go
-        * through .atomic_plane_update() and .atomic_flush() to commit plane
-        * state. Additionally, given that the plane state atomic commit occurs
-        * between CRTC disable and enable, the hardware state could also be
-        * lost due to runtime PM, requiring a full commit here. This will be
-        * fixed later after switching to atomic updates completely.
-        */
-       mutex_lock(&rcrtc->group->planes.lock);
-       rcar_du_crtc_update_planes(crtc);
-       mutex_unlock(&rcrtc->group->planes.lock);
-
-       for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
-               struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
-
-               if (plane->crtc != crtc || !plane->enabled)
-                       continue;
-
-               rcar_du_plane_setup(plane);
-       }
+       /* Start with all planes disabled. */
+       rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
 
        /* Select master sync mode. This enables display operation in master
         * sync mode (with the HSYNC and VSYNC signals configured as outputs and
@@ -434,11 +418,25 @@ void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
 
 void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
 {
+       unsigned int i;
+
        if (!rcrtc->enabled)
                return;
 
        rcar_du_crtc_get(rcrtc);
        rcar_du_crtc_start(rcrtc);
+
+       /* Commit the planes state. */
+       for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
+               struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
+
+               if (plane->plane.state->crtc != &rcrtc->crtc)
+                       continue;
+
+               rcar_du_plane_setup(plane);
+       }
+
+       rcar_du_crtc_update_planes(rcrtc);
 }
 
 /* -----------------------------------------------------------------------------
@@ -487,14 +485,7 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc)
        struct drm_device *dev = rcrtc->crtc.dev;
        unsigned long flags;
 
-       /* We need to access the hardware during atomic update, acquire a
-        * reference to the CRTC.
-        */
-       rcar_du_crtc_get(rcrtc);
-
        if (event) {
-               event->pipe = rcrtc->index;
-
                WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
                spin_lock_irqsave(&dev->event_lock, flags);
@@ -507,14 +498,7 @@ static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc)
 {
        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 
-       /* We're done, apply the configuration and drop the reference acquired
-        * in .atomic_begin().
-        */
-       mutex_lock(&rcrtc->group->planes.lock);
-       rcar_du_crtc_update_planes(crtc);
-       mutex_unlock(&rcrtc->group->planes.lock);
-
-       rcar_du_crtc_put(rcrtc);
+       rcar_du_crtc_update_planes(rcrtc);
 }
 
 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
@@ -606,11 +590,9 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
        rcrtc->mmio_offset = mmio_offsets[index];
        rcrtc->index = index;
        rcrtc->enabled = false;
-       rcrtc->plane = &rgrp->planes.planes[index % 2];
-
-       rcrtc->plane->crtc = crtc;
 
-       ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, &rcrtc->plane->plane,
+       ret = drm_crtc_init_with_planes(rcdu->ddev, crtc,
+                                       &rgrp->planes.planes[index % 2].plane,
                                        NULL, &crtc_funcs);
        if (ret < 0)
                return ret;