drm/atomic: Only update crtc->x/y if it's part of the state, v2.
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / drm_atomic_helper.c
index a900858fa2657c8dabbd81fb1ec19ab59e2af4ac..f94cc371742ef9293c9c4d74f83c1ef6b1715465 100644 (file)
@@ -331,12 +331,6 @@ mode_fixup(struct drm_atomic_state *state)
        return 0;
 }
 
-static bool
-needs_modeset(struct drm_crtc_state *state)
-{
-       return state->mode_changed || state->active_changed;
-}
-
 /**
  * drm_atomic_helper_check_modeset - validate state object for modeset changes
  * @dev: DRM device
@@ -414,7 +408,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
                        crtc_state->active_changed = true;
                }
 
-               if (!needs_modeset(crtc_state))
+               if (!drm_atomic_crtc_needs_modeset(crtc_state))
                        continue;
 
                DRM_DEBUG_ATOMIC("[CRTC:%d] needs all connectors, enable: %c, active: %c\n",
@@ -564,7 +558,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
                old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)];
 
                if (!old_crtc_state->active ||
-                   !needs_modeset(old_conn_state->crtc->state))
+                   !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))
                        continue;
 
                encoder = old_conn_state->best_encoder;
@@ -601,7 +595,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
                const struct drm_crtc_helper_funcs *funcs;
 
                /* Shut down everything that needs a full modeset. */
-               if (!needs_modeset(crtc->state))
+               if (!drm_atomic_crtc_needs_modeset(crtc->state))
                        continue;
 
                if (!old_crtc_state->active)
@@ -671,10 +665,16 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
 
        /* set legacy state in the crtc structure */
        for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+               struct drm_plane *primary = crtc->primary;
+
                crtc->mode = crtc->state->mode;
                crtc->enabled = crtc->state->enable;
-               crtc->x = crtc->primary->state->src_x >> 16;
-               crtc->y = crtc->primary->state->src_y >> 16;
+
+               if (drm_atomic_get_existing_plane_state(old_state, primary) &&
+                   primary->state->crtc == crtc) {
+                       crtc->x = primary->state->src_x >> 16;
+                       crtc->y = primary->state->src_y >> 16;
+               }
 
                if (crtc->state->enable)
                        drm_calc_timestamping_constants(crtc,
@@ -792,7 +792,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
                const struct drm_crtc_helper_funcs *funcs;
 
                /* Need to filter out CRTCs where only planes change. */
-               if (!needs_modeset(crtc->state))
+               if (!drm_atomic_crtc_needs_modeset(crtc->state))
                        continue;
 
                if (!crtc->state->active)
@@ -819,7 +819,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
                        continue;
 
                if (!connector->state->crtc->state->active ||
-                   !needs_modeset(connector->state->crtc->state))
+                   !drm_atomic_crtc_needs_modeset(connector->state->crtc->state))
                        continue;
 
                encoder = connector->state->best_encoder;
@@ -1561,8 +1561,14 @@ static int update_output_state(struct drm_atomic_state *state,
                if (crtc == set->crtc)
                        continue;
 
-               crtc_state->enable =
-                       drm_atomic_connectors_for_crtc(state, crtc);
+               if (!drm_atomic_connectors_for_crtc(state, crtc)) {
+                       ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
+                                                               NULL);
+                       if (ret < 0)
+                               return ret;
+
+                       crtc_state->active = false;
+               }
        }
 
        return 0;
@@ -1915,10 +1921,6 @@ retry:
        if (ret != 0)
                goto fail;
 
-       /* TODO: ->page_flip is the only driver callback where the core
-        * doesn't update plane->fb. For now patch it up here. */
-       plane->fb = plane->state->fb;
-
        /* Driver takes ownership of state on successful async commit. */
        return 0;
 fail: