aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2019-03-29 14:58:32 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-04-15 01:22:03 -0400
commitc14a005c1621c3b995ac9df8bf93bb4de8a3e446 (patch)
tree9471a1acbbf165da004b91accfd084f152e13b65
parent004b3938e6374f39d43cc32bd4953f2fe8b8905b (diff)
drm/amd/display: Relax requirements for CRTCs to be enabled
[Why] As long as we have at least one non-cursor plane enabled on a CRTC then the CRTC itself can remain enabled. This will allow for commits where there's an overlay plane enabled but no primary plane enabled. [How] Remove existing primary plane fb != NULL checks and replace them with the new does_crtc_have_active_plane helper. This will be called from atomic check when validating the CRTC. Since the primary plane state can now potentially be NULL we'll need to guard for that when accessing it in some of the cursor logic. Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: David Francis <David.Francis@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c56
1 files changed, 44 insertions, 12 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 ea63accc9f1f..42e643c9b6bc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3862,6 +3862,38 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc)
3862{ 3862{
3863} 3863}
3864 3864
3865static bool does_crtc_have_active_plane(struct drm_crtc_state *new_crtc_state)
3866{
3867 struct drm_atomic_state *state = new_crtc_state->state;
3868 struct drm_plane *plane;
3869 int num_active = 0;
3870
3871 drm_for_each_plane_mask(plane, state->dev, new_crtc_state->plane_mask) {
3872 struct drm_plane_state *new_plane_state;
3873
3874 /* Cursor planes are "fake". */
3875 if (plane->type == DRM_PLANE_TYPE_CURSOR)
3876 continue;
3877
3878 new_plane_state = drm_atomic_get_new_plane_state(state, plane);
3879
3880 if (!new_plane_state) {
3881 /*
3882 * The plane is enable on the CRTC and hasn't changed
3883 * state. This means that it previously passed
3884 * validation and is therefore enabled.
3885 */
3886 num_active += 1;
3887 continue;
3888 }
3889
3890 /* We need a framebuffer to be considered enabled. */
3891 num_active += (new_plane_state->fb != NULL);
3892 }
3893
3894 return num_active > 0;
3895}
3896
3865static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, 3897static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
3866 struct drm_crtc_state *state) 3898 struct drm_crtc_state *state)
3867{ 3899{
@@ -3880,6 +3912,11 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
3880 if (!dm_crtc_state->stream) 3912 if (!dm_crtc_state->stream)
3881 return 0; 3913 return 0;
3882 3914
3915 /* We want at least one hardware plane enabled to use the stream. */
3916 if (state->enable && state->active &&
3917 !does_crtc_have_active_plane(state))
3918 return -EINVAL;
3919
3883 if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) 3920 if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)
3884 return 0; 3921 return 0;
3885 3922
@@ -4849,9 +4886,13 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
4849 4886
4850 x = plane->state->crtc_x; 4887 x = plane->state->crtc_x;
4851 y = plane->state->crtc_y; 4888 y = plane->state->crtc_y;
4852 /* avivo cursor are offset into the total surface */ 4889
4853 x += crtc->primary->state->src_x >> 16; 4890 if (crtc->primary->state) {
4854 y += crtc->primary->state->src_y >> 16; 4891 /* avivo cursor are offset into the total surface */
4892 x += crtc->primary->state->src_x >> 16;
4893 y += crtc->primary->state->src_y >> 16;
4894 }
4895
4855 if (x < 0) { 4896 if (x < 0) {
4856 xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1); 4897 xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
4857 x = 0; 4898 x = 0;
@@ -5872,21 +5913,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
5872 struct amdgpu_dm_connector *aconnector = NULL; 5913 struct amdgpu_dm_connector *aconnector = NULL;
5873 struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL; 5914 struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
5874 struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL; 5915 struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
5875 struct drm_plane_state *new_plane_state = NULL;
5876 5916
5877 new_stream = NULL; 5917 new_stream = NULL;
5878 5918
5879 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); 5919 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
5880 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 5920 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
5881 acrtc = to_amdgpu_crtc(crtc); 5921 acrtc = to_amdgpu_crtc(crtc);
5882
5883 new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary);
5884
5885 if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) {
5886 ret = -EINVAL;
5887 goto fail;
5888 }
5889
5890 aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); 5922 aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
5891 5923
5892 /* TODO This hack should go away */ 5924 /* TODO This hack should go away */