drm/i915: Assign crtc correctly in load detection.
Subsystems (2)
PATCH 1/1 drm/i915: Assign crtc correctly in load detection.
drm_atomic_set_crtc_for_connector should be used, and crtc->primary->crtc is assigned by atomic_commit.
Rely on the helpers for setting this correctly, so connector_mask gets updated too.
---
Should this be applied to topic/drm-misc since atomic connector_masks are added there?
drivers/gpu/drm/i915/intel_display.c +3 -2
@@ -10553,7 +10553,9 @@ retry: goto fail; } - connector_state->crtc = crtc; + ret =drm_atomic_set_crtc_for_connector (connector_state, crtc); +if (ret) + goto fail; crtc_state =intel_atomic_get_crtc_state (state, intel_crtc);if (IS_ERR (crtc_state)) {
@@ -10597,7 +10599,6 @@ retry: old->release_fb->funcs->destroy (old->release_fb); goto fail; } - crtc->primary->crtc = crtc;/* let the connector get through one full cycle before testing */ intel_wait_for_vblank (dev, intel_crtc->pipe);
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 7 lines · Maarten Lankhorst
drm_atomic_set_crtc_for_connectorshould be used, andcrtc->primary->crtcis assigned byatomic_commit.Rely on the helpers for setting this correctly, so
connector_maskgets updated too.Signed-off-by Maarten Lankhorst <[email protected]>
Quoted 27 lines
---
Should this be applied to topic/drm-misc since atomicconnector_masksare added there?drivers/gpu/drm/i915/intel_display.c +3
-2@@ -10553,7 +10553,9 @@ retry: goto fail; } - connector_state->crtc = crtc; + ret =drm_atomic_set_crtc_for_connector (connector_state, crtc); +if (ret) + goto fail; crtc_state =intel_atomic_get_crtc_state (state, intel_crtc);if (IS_ERR (crtc_state)) {@@ -10597,7 +10599,6 @@ retry: old->release_fb->funcs->destroy (old->release_fb); goto fail; } - crtc->primary->crtc = crtc;/* let the connector get through one full cycle before testing */ intel_wait_for_vblank (dev, intel_crtc->pipe);
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Op 12-01-16 om 13:34 schreef Daniel Vetter:
Quoted 9 lines · Maarten Lankhorst
Quoted 7 lines
drm_atomic_set_crtc_for_connectorshould be used, andcrtc->primary->crtcis assigned byatomic_commit.Rely on the helpers for setting this correctly, so
connector_maskgets updated too.Signed-off-by Maarten Lankhorst <[email protected]>Reviewed-by Daniel Vetter <[email protected]>
After examining the code some more I think this fix is incomplete.
It also needs to do the same on release and if you set i915.nuclear_pageflip you'll get a WARN since mode_blob's not set. Fixing this will break release_load_detect which doesn't unset it.
Would the code work?
Cc'ing Ville since he may be able to test it.
--- >8 ---
drm/i915: Use atomic state to obtain load detection crtc.
---
drivers/gpu/drm/i915/intel_display.c +74 -54
@@ -10409,6 +10409,7 @@ mode_fits_in_fbdev(struct drm_device *dev,if (obj->base.size < mode->vdisplay * fb->pitches[0 ])return NULL ; +drm_framebuffer_reference (fb);return fb;#else return NULL ;
@@ -10474,6 +10475,9 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, encoder->base.id, encoder->name); retry: + old->old_pipe_config =NULL ; + old->old_plane_state =NULL ; + ret =drm_modeset_lock (&config->connection_mutex, ctx);if (ret) goto fail;
@@ -10489,24 +10493,15 @@ retry:*/ /* See if we already have a CRTC for this connector */ -if (encoder->crtc) { - crtc = encoder->crtc; +if (connector->state->crtc) { + crtc = connector->state->crtc; ret =drm_modeset_lock (&crtc->mutex, ctx);if (ret) goto fail; - ret =drm_modeset_lock (&crtc->primary->mutex, ctx); -if (ret) - goto fail; - - old->dpms_mode = connector->dpms; - old->load_detect_temp = false;/* Make sure the crtc and connector are running */ -if (connector->dpms !=DRM_MODE_DPMS_ON ) - connector->funcs->dpms (connector,DRM_MODE_DPMS_ON ); - -return true; + goto found; }/* Find an unused one (if possible) */
@@ -10514,8 +10509,15 @@ retry: i++;if (!(encoder->possible_crtcs & (1 << i)))continue ; -if (possible_crtc->state->enable) + + ret =drm_modeset_lock (&crtc->mutex, ctx); +if (ret) + goto fail; + +if (possible_crtc->state->enable) { +drm_modeset_unlock (&crtc->mutex);continue ; + } crtc = possible_crtc;break ;
@@ -10529,17 +10531,19 @@ retry: goto fail; } - ret =drm_modeset_lock (&crtc->mutex, ctx); -if (ret) - goto fail; +found: + intel_crtc =to_intel_crtc (crtc); + ret =drm_modeset_lock (&crtc->primary->mutex, ctx);if (ret) goto fail; - intel_crtc =to_intel_crtc (crtc); - old->dpms_mode = connector->dpms; - old->load_detect_temp = true; - old->release_fb =NULL ; + old->old_pipe_config =intel_crtc_duplicate_state (crtc); + old->old_plane_state =intel_plane_duplicate_state (crtc->primary); +if (!old->old_pipe_config || !old->old_plane_state) { + ret = -ENOMEM ; + goto fail; + } state =drm_atomic_state_alloc (dev);if (!state)
@@ -10553,7 +10557,9 @@ retry: goto fail; } - connector_state->crtc = crtc; + ret =drm_atomic_set_crtc_for_connector (connector_state, crtc); +if (ret) + goto fail; crtc_state =intel_atomic_get_crtc_state (state, intel_crtc);if (IS_ERR (crtc_state)) {
@@ -10577,7 +10583,6 @@ retry:if (fb ==NULL ) {DRM_DEBUG_KMS ("creating tmp fb for load-detection\n" ); fb =intel_framebuffer_create_for_mode (dev, mode,24 ,32 ); - old->release_fb = fb; }else DRM_DEBUG_KMS ("reusing fbdev for load-detection framebuffer\n" );if (IS_ERR (fb)) {
@@ -10589,15 +10594,16 @@ retry:if (ret) goto fail; -drm_mode_copy (&crtc_state->base.mode, mode); +drm_framebuffer_unreference (fb); + + ret =drm_atomic_set_mode_for_crtc (&crtc_state->base, mode); +if (ret) + goto fail;if (drm_atomic_commit (state)) {DRM_DEBUG_KMS ("failed to set mode on load-detect pipe\n" ); -if (old->release_fb) - old->release_fb->funcs->destroy (old->release_fb); goto fail; } - crtc->primary->crtc = crtc;/* let the connector get through one full cycle before testing */ intel_wait_for_vblank (dev, intel_crtc->pipe);
@@ -10607,6 +10613,12 @@ fail:drm_atomic_state_free (state); state =NULL ; +if (old->old_pipe_config) +intel_crtc_destroy_state (crtc, old->old_pipe_config); + +if (old->old_plane_state) +intel_plane_destroy_state (crtc->primary, old->old_plane_state); +if (ret == -EDEADLK ) {drm_modeset_backoff (ctx); goto retry;
@@ -10623,61 +10635,69 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,struct intel_encoder *intel_encoder =intel_attached_encoder (connector);struct drm_encoder *encoder = &intel_encoder->base; -struct drm_crtc *crtc = encoder->crtc; +struct drm_crtc *crtc = connector->state->crtc;struct intel_crtc *intel_crtc =to_intel_crtc (crtc);struct drm_atomic_state *state;struct drm_connector_state *connector_state;struct intel_crtc_state *crtc_state; +struct drm_plane_state *plane_state;int ret;DRM_DEBUG_KMS ("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n" , connector->base.id, connector->name, encoder->base.id, encoder->name); -if (old->load_detect_temp) { - state =drm_atomic_state_alloc (dev); -if (!state) - goto fail; +if (!old->old_pipe_config) +return ; - state->acquire_ctx = ctx; + state =drm_atomic_state_alloc (dev); +if (!state) + goto fail; - connector_state =drm_atomic_get_connector_state (state, connector); -if (IS_ERR (connector_state)) - goto fail; + state->acquire_ctx = ctx; - crtc_state =intel_atomic_get_crtc_state (state, intel_crtc); -if (IS_ERR (crtc_state)) - goto fail; + connector_state =drm_atomic_get_connector_state (state, connector); +if (IS_ERR (connector_state)) + goto fail; - connector_state->crtc =NULL ; + crtc_state =intel_atomic_get_crtc_state (state, intel_crtc); +if (IS_ERR (crtc_state)) + goto fail; - crtc_state->base.enable = crtc_state->base.active = false; + plane_state =drm_atomic_get_plane_state (state, crtc->primary); +if (IS_ERR (plane_state)) + goto fail; - ret =intel_modeset_setup_plane_state (state, crtc,NULL ,NULL , -0 ,0 ); +if (!old->old_pipe_config->enable) { + ret =drm_atomic_set_crtc_for_connector (connector_state,NULL );if (ret) goto fail; + } - ret =drm_atomic_commit (state); -if (ret) - goto fail; + crtc_state->base.enable = old->old_pipe_config->enable; + crtc_state->base.active = old->old_pipe_config->active; -if (old->release_fb) { -drm_framebuffer_unregister_private (old->release_fb); -drm_framebuffer_unreference (old->release_fb); - } +drm_atomic_set_fb_for_plane (plane_state, old->old_plane_state->fb); + ret =drm_atomic_set_crtc_for_plane (plane_state, old->old_plane_state->crtc); +if (ret) + goto fail; -return ; - } + old->old_plane_state->state = plane_state->state; + *plane_state = *old->old_plane_state; -/* Switch crtc and encoder back off if necessary */ -if (old->dpms_mode !=DRM_MODE_DPMS_ON ) - connector->funcs->dpms (connector, old->dpms_mode); + ret =drm_atomic_commit (state); +if (ret) + goto fail; +intel_plane_destroy_state (crtc->primary, old->old_plane_state); +intel_crtc_destroy_state (crtc, old->old_pipe_config);return ; + fail:DRM_DEBUG_KMS ("Couldn't release load detect pipe.\n" );drm_atomic_state_free (state); +intel_plane_destroy_state (crtc->primary, old->old_plane_state); +intel_crtc_destroy_state (crtc, old->old_pipe_config); } static int i9xx_pll_refclk(struct drm_device *dev,
drivers/gpu/drm/i915/intel_drv.h +2 -2
@@ -932,8 +932,8 @@ struct intel_unpin_work {struct intel_load_detect_pipe {struct drm_framebuffer *release_fb; -bool load_detect_temp; -int dpms_mode; +struct drm_crtc_state *old_pipe_config; +struct drm_plane_state *old_plane_state; }; static inline struct intel_encoder *
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx