From: Andrey Grodzovsky <[email protected]>

Split into update crtcs and update plane functions.

Change-Id: I57a739070861553de9b787f995e44a1da4e3c2d0
Signed-off-by: Andrey Grodzovsky <[email protected]>
Reviewed-by: Harry Wentland <[email protected]>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 453 ++++++++++++----------
 1 file changed, 257 insertions(+), 196 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 5218432361fd..e24c44f6720b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1660,12 +1660,6 @@ static bool modeset_required(struct drm_crtc_state 
*crtc_state,
                             struct dc_stream_state *new_stream,
                             struct dc_stream_state *old_stream)
 {
-       if (dc_is_stream_unchanged(new_stream, old_stream)) {
-               crtc_state->mode_changed = false;
-               DRM_DEBUG_KMS("Mode change not required, setting mode_changed 
to %d",
-                             crtc_state->mode_changed);
-       }
-
        if (!drm_atomic_crtc_needs_modeset(crtc_state))
                return false;
 
@@ -3990,9 +3984,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
                        continue;
                }
 
-               if (!fb || !crtc || pcrtc != crtc || !crtc->state->active ||
-                               (!crtc->state->planes_changed &&
-                                               
!pcrtc->state->color_mgmt_changed))
+               if (!fb || !crtc || pcrtc != crtc || !crtc->state->active)
                        continue;
 
                pflip_needed = !state->allow_modeset;
@@ -4469,91 +4461,77 @@ static int do_aquire_global_lock(
        return ret < 0 ? ret : 0;
 }
 
-int amdgpu_dm_atomic_check(struct drm_device *dev,
-                       struct drm_atomic_state *state)
+static int dm_update_crtcs_state(
+               struct dc *dc,
+               struct drm_atomic_state *state,
+               bool enable,
+               bool *lock_and_validation_needed)
 {
        struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
-       struct drm_plane *plane;
-       struct drm_plane_state *plane_state;
-       int i, j;
-       int ret;
-       struct amdgpu_device *adev = dev->dev_private;
-       struct dc *dc = adev->dm.dc;
-       struct drm_connector *connector;
-       struct drm_connector_state *conn_state;
+       int i;
        struct dm_crtc_state *old_acrtc_state, *new_acrtc_state;
        struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
-       bool pflip_needed  = !state->allow_modeset;
-
-       /*
-        * This bool will be set for true for any modeset/reset
-        * or plane update which implies non fast surface update.
-        */
-       bool lock_and_validation_needed = false;
+       int ret = 0;
 
-       ret = drm_atomic_helper_check_modeset(dev, state);
+       /*TODO Move this code into dm_crtc_atomic_check once we get rid of 
dc_validation_set */
+       /* update changed items */
+       for_each_crtc_in_state(state, crtc, crtc_state, i) {
+               struct amdgpu_crtc *acrtc = NULL;
+               struct amdgpu_connector *aconnector = NULL;
+               struct dc_stream_state *new_stream = NULL;
+               struct drm_connector_state *conn_state = NULL;
+               struct dm_connector_state *dm_conn_state = NULL;
 
-       if (ret) {
-               DRM_ERROR("Atomic state validation failed with error :%d !\n", 
ret);
-               return ret;
-       }
 
-       /* Remove exiting planes if they are disabled or their CRTC is updated 
*/
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
+               old_acrtc_state = to_dm_crtc_state(crtc->state);
                new_acrtc_state = to_dm_crtc_state(crtc_state);
+               acrtc = to_amdgpu_crtc(crtc);
 
-               if (pflip_needed)
-                       continue;
+               aconnector = 
amdgpu_dm_find_first_crct_matching_connector(state, crtc, true);
 
-               for_each_plane_in_state(state, plane, plane_state, j) {
-                       struct drm_crtc *plane_crtc = plane_state->crtc;
-                       struct dm_plane_state *dm_plane_state = 
to_dm_plane_state(plane_state);
+               /* TODO This hack should go away */
+               if (aconnector && aconnector->dc_sink) {
+                       conn_state = drm_atomic_get_connector_state(state,
+                                                                   
&aconnector->base);
 
-                       if (plane->type == DRM_PLANE_TYPE_CURSOR)
-                               continue;
-
-                       if (crtc != plane_crtc || !dm_plane_state->dc_state)
-                               continue;
+                       if (IS_ERR(conn_state)) {
+                               ret = PTR_ERR_OR_ZERO(conn_state);
+                               break;
+                       }
 
-                       WARN_ON(!new_acrtc_state->stream);
+                       dm_conn_state = to_dm_connector_state(conn_state);
 
-                       if (drm_atomic_plane_disabling(plane->state, 
plane_state) ||
-                                       
drm_atomic_crtc_needs_modeset(crtc_state)) {
-                               if (!dc_remove_plane_from_context(
-                                               dc,
-                                               new_acrtc_state->stream,
-                                               dm_plane_state->dc_state,
-                                               dm_state->context)) {
+                       new_stream = create_stream_for_sink(aconnector,
+                                                           &crtc_state->mode,
+                                                           dm_conn_state);
 
-                                       ret = EINVAL;
-                                       goto fail;
-                               }
+                       /*
+                        * we can have no stream on ACTION_SET if a display
+                        * was disconnected during S3, in this case it not and
+                        * error, the OS will be updated after detection, and
+                        * do the right thing on next atomic commit
+                        */
 
+                       if (!new_stream) {
+                               DRM_DEBUG_KMS("%s: Failed to create new stream 
for crtc %d\n",
+                                               __func__, acrtc->base.base.id);
+                               break;
                        }
+               }
 
-                       dc_plane_state_release(dm_plane_state->dc_state);
-                       dm_plane_state->dc_state = NULL;
+               if (dc_is_stream_unchanged(new_stream,
+                               old_acrtc_state->stream)) {
 
-                       DRM_DEBUG_KMS("Disabling DRM plane: %d on DRM crtc 
%d\n",
-                                       plane->base.id, crtc->base.id);
-               }
-       }
+                               crtc_state->mode_changed = false;
 
-       /*TODO Move this code into dm_crtc_atomic_check once we get rid of 
dc_validation_set */
-       /* update changed items */
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
-               struct amdgpu_crtc *acrtc = NULL;
-               struct amdgpu_connector *aconnector = NULL;
-               struct dc_stream_state *new_stream = NULL;
-               struct drm_connector_state *conn_state = NULL;
-               struct dm_connector_state *dm_conn_state = NULL;
+                               DRM_DEBUG_KMS("Mode change not required, 
setting mode_changed to %d",
+                                             crtc_state->mode_changed);
+               }
 
-               old_acrtc_state = to_dm_crtc_state(crtc->state);
-               new_acrtc_state = to_dm_crtc_state(crtc_state);
-               acrtc = to_amdgpu_crtc(crtc);
 
-               aconnector = 
amdgpu_dm_find_first_crct_matching_connector(state, crtc, true);
+               if (!drm_atomic_crtc_needs_modeset(crtc_state))
+                               continue;
 
                DRM_DEBUG_KMS(
                        "amdgpu_crtc id:%d crtc_state_flags: enable:%d, 
active:%d, "
@@ -4567,109 +4545,252 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
                        crtc_state->active_changed,
                        crtc_state->connectors_changed);
 
-               if (modereset_required(crtc_state)) {
+               /* Remove stream for any changed/disabled CRTC */
+               if (!enable) {
+
+                       if (!old_acrtc_state->stream)
+                               continue;
+
+                       DRM_DEBUG_KMS("Disabling DRM crtc: %d\n",
+                                       crtc->base.id);
 
                        /* i.e. reset mode */
-                       if (new_acrtc_state->stream) {
+                       if (!dc_remove_stream_from_ctx(
+                                       dc,
+                                       dm_state->context,
+                                       old_acrtc_state->stream)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       dc_stream_release(old_acrtc_state->stream);
+                       new_acrtc_state->stream = NULL;
+
+                       *lock_and_validation_needed = true;
+
+               } else {/* Add stream for any updated/enabled CRTC */
+
+                       if (modereset_required(crtc_state))
+                               continue;
+
+                       if (modeset_required(crtc_state, new_stream,
+                                            old_acrtc_state->stream)) {
+
+                               WARN_ON(new_acrtc_state->stream);
+
+                               new_acrtc_state->stream = new_stream;
+                               dc_stream_retain(new_stream);
+
+                               DRM_DEBUG_KMS("Enabling DRM crtc: %d\n",
+                                                       crtc->base.id);
 
-                               if (!dc_remove_stream_from_ctx(
+                               if (!dc_add_stream_to_ctx(
                                                dc,
                                                dm_state->context,
                                                new_acrtc_state->stream)) {
                                        ret = -EINVAL;
-                                       goto fail;
+                                       break;
                                }
 
-                               dc_stream_release(new_acrtc_state->stream);
-                               new_acrtc_state->stream = NULL;
-
-                               lock_and_validation_needed = true;
+                               *lock_and_validation_needed = true;
                        }
+               }
 
-               } else {
+               /* Release extra reference */
+               if (new_stream)
+                        dc_stream_release(new_stream);
+       }
 
-                       if (aconnector) {
-                               conn_state = 
drm_atomic_get_connector_state(state,
-                                                                           
&aconnector->base);
+       return ret;
+}
 
-                               if (IS_ERR(conn_state)) {
-                                       ret = PTR_ERR_OR_ZERO(conn_state);
-                                       goto fail;
-                               }
+static int dm_update_planes_state(
+               struct dc *dc,
+               struct drm_atomic_state *state,
+               bool enable,
+               bool *lock_and_validation_needed)
+{
+       struct drm_crtc *new_plane_crtc, *old_plane_crtc;
+       struct drm_crtc_state *new_crtc_state;
+       struct drm_plane *plane;
+       struct drm_plane_state *old_plane_state, *new_plane_state;
+       struct dm_crtc_state *new_acrtc_state, *old_acrtc_state;
+       struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
+       struct dm_plane_state *new_dm_plane_state, *old_dm_plane_state;
+       int i ;
+       /* TODO return page_flip_needed() function */
+       bool pflip_needed  = !state->allow_modeset;
+       int ret = 0;
 
-                               dm_conn_state = 
to_dm_connector_state(conn_state);
+       if (pflip_needed)
+               return ret;
 
-                               new_stream = create_stream_for_sink(aconnector,
-                                                                   
&crtc_state->mode,
-                                                                   
dm_conn_state);
+       /* Add new planes */
+       for_each_oldnew_plane_in_state(state, plane, old_plane_state, 
new_plane_state, i) {
+               new_plane_crtc = new_plane_state->crtc;
+               old_plane_crtc = old_plane_state->crtc;
+               new_dm_plane_state = to_dm_plane_state(new_plane_state);
+               old_dm_plane_state = to_dm_plane_state(old_plane_state);
+
+               /*TODO Implement atomic check for cursor plane */
+               if (plane->type == DRM_PLANE_TYPE_CURSOR)
+                       continue;
 
-                               /*
-                                * we can have no stream on ACTION_SET if a 
display
-                                * was disconnected during S3, in this case it 
not and
-                                * error, the OS will be updated after 
detection, and
-                                * do the right thing on next atomic commit
-                                */
+               /* Remove any changed/removed planes */
+               if (!enable) {
 
-                               if (!new_stream) {
-                                       DRM_DEBUG_KMS("%s: Failed to create new 
stream for crtc %d\n",
-                                                       __func__, 
acrtc->base.base.id);
-                                       break;
-                               }
+                       if (!old_plane_crtc)
+                               continue;
+
+                       old_acrtc_state = to_dm_crtc_state(
+                                       drm_atomic_get_old_crtc_state(
+                                                       state,
+                                                       old_plane_crtc));
+
+                       if (!old_acrtc_state->stream)
+                               continue;
+
+                       DRM_DEBUG_KMS("Disabling DRM plane: %d on DRM crtc 
%d\n",
+                                       plane->base.id, 
old_plane_crtc->base.id);
 
+                       if (!dc_remove_plane_from_context(
+                                       dc,
+                                       old_acrtc_state->stream,
+                                       old_dm_plane_state->dc_state,
+                                       dm_state->context)) {
 
+                               ret = EINVAL;
+                               return ret;
                        }
 
-                       if (modeset_required(crtc_state, new_stream,
-                                            old_acrtc_state->stream)) {
 
-                               if (new_acrtc_state->stream) {
+                       dc_plane_state_release(old_dm_plane_state->dc_state);
+                       new_dm_plane_state->dc_state = NULL;
 
-                                       if (!dc_remove_stream_from_ctx(
-                                                       dc,
-                                                       dm_state->context,
-                                                       
new_acrtc_state->stream)) {
-                                               ret = -EINVAL;
-                                               goto fail;
-                                       }
+                       *lock_and_validation_needed = true;
 
+               } else { /* Add new planes */
 
-                                       
dc_stream_release(new_acrtc_state->stream);
-                               }
+                       if (drm_atomic_plane_disabling(plane->state, 
new_plane_state))
+                               continue;
 
-                               new_acrtc_state->stream = new_stream;
+                       if (!new_plane_crtc)
+                               continue;
 
-                               if (!dc_add_stream_to_ctx(
-                                               dc,
-                                               dm_state->context,
-                                               new_acrtc_state->stream)) {
-                                       ret = -EINVAL;
-                                       goto fail;
-                               }
+                       new_crtc_state = drm_atomic_get_new_crtc_state(state, 
new_plane_crtc);
+                       new_acrtc_state = to_dm_crtc_state(new_crtc_state);
 
-                               lock_and_validation_needed = true;
-                       } else {
-                               /*
-                                * The new stream is unused, so we release it
-                                */
-                               if (new_stream)
-                                       dc_stream_release(new_stream);
+                       if (!new_acrtc_state->stream)
+                               continue;
+
+
+                       WARN_ON(new_dm_plane_state->dc_state);
+
+                       new_dm_plane_state->dc_state = 
dc_create_plane_state(dc);
+
+                       DRM_DEBUG_KMS("Enabling DRM plane: %d on DRM crtc %d\n",
+                                       plane->base.id, 
new_plane_crtc->base.id);
+
+                       if (!new_dm_plane_state->dc_state) {
+                               ret = -EINVAL;
+                               return ret;
+                       }
+
+                       ret = fill_plane_attributes(
+                               new_plane_crtc->dev->dev_private,
+                               new_dm_plane_state->dc_state,
+                               new_plane_state,
+                               new_crtc_state,
+                               false);
+                       if (ret)
+                               return ret;
+
+
+                       if (!dc_add_plane_to_context(
+                                       dc,
+                                       new_acrtc_state->stream,
+                                       new_dm_plane_state->dc_state,
+                                       dm_state->context)) {
 
+                               ret = -EINVAL;
+                               return ret;
                        }
+
+                       *lock_and_validation_needed = true;
                }
+       }
 
 
-               /*
-                * Hack: Commit needs planes right now, specifically for gamma
-                * TODO rework commit to check CRTC for gamma change
-                */
-               if (crtc_state->color_mgmt_changed) {
+       return ret;
+}
+
+int amdgpu_dm_atomic_check(struct drm_device *dev,
+                       struct drm_atomic_state *state)
+{
+       int i;
+       int ret;
+       struct amdgpu_device *adev = dev->dev_private;
+       struct dc *dc = adev->dm.dc;
+       struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
+       struct drm_connector *connector;
+       struct drm_connector_state *conn_state;
+       struct drm_crtc *crtc;
+       struct drm_crtc_state *crtc_state;
+
+       /*
+        * This bool will be set for true for any modeset/reset
+        * or plane update which implies non fast surface update.
+        */
+       bool lock_and_validation_needed = false;
+
+       ret = drm_atomic_helper_check_modeset(dev, state);
 
+       if (ret) {
+               DRM_ERROR("Atomic state validation failed with error :%d !\n", 
ret);
+               return ret;
+       }
+
+       /*
+        * Hack: Commit needs planes right now, specifically for gamma
+        * TODO rework commit to check CRTC for gamma change
+        */
+       for_each_crtc_in_state(state, crtc, crtc_state, i) {
+               if (crtc_state->color_mgmt_changed) {
                        ret = drm_atomic_add_affected_planes(state, crtc);
                        if (ret)
                                goto fail;
                }
        }
 
+       /* Remove exiting planes if they are modified */
+       ret = dm_update_planes_state(dc, state, false, 
&lock_and_validation_needed);
+       if (ret) {
+               goto fail;
+       }
+
+       /* Disable all crtcs which require disable */
+       ret = dm_update_crtcs_state(dc, state, false, 
&lock_and_validation_needed);
+       if (ret) {
+               goto fail;
+       }
+
+       /* Enable all crtcs which require enable */
+       ret = dm_update_crtcs_state(dc, state, true, 
&lock_and_validation_needed);
+       if (ret) {
+               goto fail;
+       }
+
+       /* Add new/modified planes */
+       ret = dm_update_planes_state(dc, state, true, 
&lock_and_validation_needed);
+       if (ret) {
+               goto fail;
+       }
+
+        /* Run this here since we want to validate the streams we created */
+        ret = drm_atomic_helper_check_planes(dev, state);
+        if (ret)
+                goto fail;
+
        /* Check scaling and undersacn changes*/
        /*TODO Removed scaling changes validation due to inability to commit
         * new stream into context w\o causing full reset. Need to
@@ -4694,66 +4815,6 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
                lock_and_validation_needed = true;
        }
 
-       /* Add new planes */
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
-               new_acrtc_state = to_dm_crtc_state(crtc_state);
-
-               if (pflip_needed)
-                       continue;
-
-               for_each_plane_in_state(state, plane, plane_state, j) {
-                       struct drm_crtc *plane_crtc = plane_state->crtc;
-                       struct dm_plane_state *dm_plane_state = 
to_dm_plane_state(plane_state);
-
-                       /*TODO Implement atomic check for cursor plane */
-                       if (plane->type == DRM_PLANE_TYPE_CURSOR)
-                               continue;
-
-                       if (crtc != plane_crtc)
-                               continue;
-
-                       if (!drm_atomic_plane_disabling(plane->state, 
plane_state)) {
-                               struct dc_plane_state *dc_plane_state;
-
-                               WARN_ON(!new_acrtc_state->stream);
-
-                               dc_plane_state = dc_create_plane_state(dc);
-
-                               WARN_ON(dm_plane_state->dc_state);
-
-                               dm_plane_state->dc_state = dc_plane_state;
-
-                               ret = fill_plane_attributes(
-                                       plane_crtc->dev->dev_private,
-                                       dc_plane_state,
-                                       plane_state,
-                                       crtc_state,
-                                       false);
-                               if (ret)
-                                       goto fail;
-
-
-                               if (!dc_add_plane_to_context(
-                                               dc,
-                                               new_acrtc_state->stream,
-                                               dc_plane_state,
-                                               dm_state->context)) {
-
-                                       ret = EINVAL;
-                                       goto fail;
-                               }
-
-
-                               lock_and_validation_needed = true;
-                       }
-               }
-       }
-
-       /* Run this here since we want to validate the streams we created */
-       ret = drm_atomic_helper_check_planes(dev, state);
-       if (ret)
-               goto fail;
-
        /*
         * For full updates case when
         * removing/adding/updating  streams on once CRTC while flipping
@@ -4786,7 +4847,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev,
        else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS)
                DRM_DEBUG_KMS("Atomic check stopped due to to signal.\n");
        else
-               DRM_ERROR("Atomic check failed with err: %d .\n", ret);
+               DRM_ERROR("Atomic check failed with err: %d \n", ret);
 
        return ret;
 }
-- 
2.11.0

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to