From: Ville Syrj?l? <ville.syrjala at linux.intel.com> Use the new_crtc and new_encoder pointes inside the intel_encoder and intel_connector structures instead of swapping the crtc and encoder pointers in the drm base structures around the disable calls. Signed-off-by: Ville Syrj?l? <ville.syrjala at linux.intel.com> --- drivers/gpu/drm/i915/intel_atomic.c | 115 ++++++++++++++-------------------- 1 files changed, 47 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 3717e89..3f093d6 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -115,43 +115,57 @@ struct intel_atomic_state { struct drm_encoder *saved_encoders; }; -static void update_connectors_bitmask(struct drm_crtc *crtc, +static void update_connectors_bitmask(struct intel_crtc *intel_crtc, unsigned long *connectors_bitmask) { - struct drm_device *dev = crtc->dev; - struct drm_connector *connector; + struct drm_device *dev = intel_crtc->base.dev; + struct intel_connector *intel_connector; unsigned int i = 0; *connectors_bitmask = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder && connector->encoder->crtc == crtc) + list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) { + if (intel_connector->new_encoder && + intel_connector->new_encoder->new_crtc == intel_crtc) __set_bit(i, connectors_bitmask); i++; } } -static void update_encoders_bitmask(struct drm_crtc *crtc, +static void update_encoders_bitmask(struct intel_crtc *intel_crtc, unsigned long *encoders_bitmask) { - struct drm_device *dev = crtc->dev; - struct drm_encoder *encoder; + struct drm_device *dev = intel_crtc->base.dev; + struct intel_encoder *intel_encoder; unsigned int i = 0; *encoders_bitmask = 0; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) + list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list, base.head) { + if (intel_encoder->new_crtc == intel_crtc) __set_bit(i, encoders_bitmask); i++; } } +static bool intel_encoder_in_use(struct intel_encoder *intel_encoder) +{ + struct drm_device *dev = intel_encoder->base.dev; + struct intel_connector *intel_connector; + + list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) + if (intel_connector->new_encoder == intel_encoder) + return true; + + return false; +} + static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, int count_ids) { struct drm_crtc *crtc = s->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = crtc->dev; struct drm_connector *connectors[count_ids]; struct drm_connector *connector; @@ -184,6 +198,9 @@ static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, i } list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_encoder *intel_encoder; + for (i = 0; i < count_ids; i++) { if (connector == connectors[i]) break; @@ -192,25 +209,28 @@ static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, i /* this connector isn't in the set */ if (i == count_ids) { /* remove the link to the encoder if this crtc was set to drive it */ - if (connector->encoder && connector->encoder->crtc == crtc) - connector->encoder = NULL; + if (intel_connector->new_encoder && + intel_connector->new_encoder->new_crtc == intel_crtc) + intel_connector->new_encoder = NULL; continue; } - encoder = intel_best_encoder(connector); + intel_encoder = to_intel_encoder(intel_best_encoder(connector)); - connector->encoder = encoder; - encoder->crtc = crtc; + intel_connector->new_encoder = intel_encoder; + intel_encoder->new_crtc = intel_crtc; } /* prune dangling encoder->crtc links pointing to this crtc */ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc && !drm_helper_encoder_in_use(encoder)) - encoder->crtc = NULL; + struct intel_encoder *intel_encoder = to_intel_encoder(encoder); + + if (intel_encoder->new_crtc == intel_crtc && !intel_encoder_in_use(intel_encoder)) + intel_encoder->new_crtc = NULL; } - update_connectors_bitmask(s->crtc, &s->connectors_bitmask); - update_encoders_bitmask(s->crtc, &s->encoders_bitmask); + update_connectors_bitmask(intel_crtc, &s->connectors_bitmask); + update_encoders_bitmask(intel_crtc, &s->encoders_bitmask); return 0; } @@ -232,19 +252,6 @@ static size_t intel_atomic_state_size(const struct drm_device *dev) num_plane * sizeof state->saved_planes[0]; } - -static void populate_old(struct drm_device *dev) -{ - struct drm_encoder *encoder; - struct drm_connector *connector; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - encoder->old_crtc = encoder->crtc; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->old_encoder = connector->encoder; -} - static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file, uint32_t flags, uint64_t user_data) { @@ -275,8 +282,6 @@ static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file, state->saved_crtcs = (struct intel_crtc *)(state->saved_encoders + num_encoder); state->saved_planes = (struct drm_plane *)(state->saved_crtcs + num_crtc); - populate_old(dev); - i = 0; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct intel_crtc_state *s = &state->crtc[i++]; @@ -297,8 +302,8 @@ static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file, s->old.x = crtc->x; s->old.y = crtc->y; - update_connectors_bitmask(crtc, &s->connectors_bitmask); - update_encoders_bitmask(crtc, &s->encoders_bitmask); + update_connectors_bitmask(intel_crtc, &s->connectors_bitmask); + update_encoders_bitmask(intel_crtc, &s->encoders_bitmask); s->old.connectors_bitmask = s->connectors_bitmask; s->old.encoders_bitmask = s->encoders_bitmask; @@ -1045,39 +1050,11 @@ static void queue_remaining_events(struct drm_device *dev, struct intel_atomic_s } } -static void swap_old_new(struct drm_device *dev, - struct intel_atomic_state *s) -{ - struct drm_encoder *encoder; - struct drm_connector *connector; - int i; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - swap(encoder->crtc, encoder->old_crtc); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - swap(connector->encoder, connector->old_encoder); - - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct intel_crtc_state *st = &s->crtc[i]; - struct drm_crtc *crtc = st->crtc; - - swap(crtc->enabled, st->old.enabled); - } -} - static int apply_config(struct drm_device *dev, struct intel_atomic_state *s) { int i, ret; - /* - * FIXME -` * Hackish way to make crtc_disable() see the current - * state (actually just some select pieces of it). - */ - swap_old_new(dev, s); - for (i = 0; i < dev->mode_config.num_crtc; i++) { struct intel_crtc_state *st = &s->crtc[i]; @@ -1097,8 +1074,7 @@ static int apply_config(struct drm_device *dev, crtc_prepare(st, st->crtc); } - /* Undo the hack above. */ - swap_old_new(dev, s); + intel_modeset_commit_output_state(dev); for (i = 0; i < dev->mode_config.num_crtc; i++) { struct intel_crtc_state *st = &s->crtc[i]; @@ -1204,6 +1180,9 @@ static void restore_state(struct drm_device *dev, list_for_each_entry(plane, &dev->mode_config.plane_list, head) *plane = s->saved_planes[i++]; + /* must restore the new_crtc and new_encoder pointers as well */ + intel_modeset_update_staged_output_state(dev); + /* FIXME props etc. */ /* was the hardware state clobbered? */ @@ -1318,8 +1297,9 @@ static int check_crtc(struct intel_crtc_state *s) list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - if (encoder->crtc != crtc) + if (intel_encoder->new_crtc != intel_crtc) continue; if (!encoder_funcs->mode_fixup(encoder, &crtc->mode, &crtc->hwmode)) @@ -1693,7 +1673,6 @@ static int intel_atomic_commit(struct drm_device *dev, void *state) update_props(dev, s); - intel_modeset_update_staged_output_state(dev); return 0; } -- 1.7.8.6