On Tue, Jan 03, 2017 at 01:01:51PM -0800, Dhinakaran Pandiyan wrote: > Make use of the added MST helpers to find, allocate and release link bw > for atomic modesets. > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@xxxxxxxxx> > --- > drivers/gpu/drm/i915/intel_display.c | 39 +++++++++++++++++++++++++++++++++++- > drivers/gpu/drm/i915/intel_dp_mst.c | 36 ++++++++++++++++++++++++++++++++- > drivers/gpu/drm/i915/intel_drv.h | 3 +++ > 3 files changed, 76 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index ab72858..71e2ac7 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -14072,6 +14072,40 @@ static int calc_watermark_data(struct drm_atomic_state *state) > return 0; > } > > +static int intel_mst_clear_config(struct drm_atomic_state *state) > +{ > + struct drm_crtc_state *crtc_state; > + struct drm_crtc *crtc; > + struct drm_connector *connector; > + struct drm_connector_state *connector_state; > + int i, j; > + > + for_each_crtc_in_state(state, crtc, crtc_state, i) { > + if (!crtc_state->active_changed || crtc_state->active) > + continue; I don't think the double-loop is needed. > + > + for_each_connector_in_state(state, connector, connector_state, j) { > + struct intel_encoder *encoder; > + struct drm_crtc *curr_crtc; > + int slots; > + > + encoder = to_intel_encoder(connector->state->best_encoder); > + if (encoder->type != INTEL_OUTPUT_DP_MST) > + continue; > + > + curr_crtc = connector->state->crtc; > + if (curr_crtc && crtc == curr_crtc) { > + slots = to_intel_crtc_state(crtc->state)->dp_m_n.tu; > + return intel_dp_mst_reset_vcpi(encoder, > + connector_state, > + slots); > + } Hm, I think it might be useful to have a generic atomic_release function for connectors in the core atomic helpers. E.g. something like the below: diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index b4dfd1e1a4f0..ce55e87b50e5 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -385,8 +385,12 @@ mode_fixup(struct drm_atomic_state *state) WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc); - if (!conn_state->crtc || !conn_state->best_encoder) + if (!conn_state->crtc || !conn_state->best_encoder) { + if (connector->helper_private->atomic_release) + connector->helper_private->atomic_release(connector, + conn_state); continue; + } crtc_state = drm_atomic_get_existing_crtc_state(state, conn_state->crtc); I think we'll have other connectors in the future where we need to drop shared resources in a similar fashion. Cheers, Daniel > + } > + } > + > + return 0; > +} > + > /** > * intel_atomic_check - validate state object > * @dev: drm device > @@ -14142,8 +14176,11 @@ static int intel_atomic_check(struct drm_device *dev, > } > > if (any_ms) { > - ret = intel_modeset_checks(state); > + ret = intel_mst_clear_config(state); > + if (ret) > + return ret; > > + ret = intel_modeset_checks(state); > if (ret) > return ret; > } else { > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > index 02a1e2c..331909b 100644 > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > @@ -44,6 +44,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, > int lane_count, slots; > const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; > int mst_pbn; > + struct drm_dp_mst_topology_state *topology_state; > > pipe_config->has_pch_encoder = false; > bpp = 24; > @@ -65,7 +66,18 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, > mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp); > > pipe_config->pbn = mst_pbn; > - slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); > + > + topology_state = drm_atomic_get_mst_topology_state(state, > + &intel_dp->mst_mgr); > + if (topology_state == NULL) > + return false; > + > + slots = drm_dp_atomic_find_vcpi_slots(topology_state, connector->port, > + mst_pbn); > + if (slots < 0) { > + DRM_DEBUG_KMS("not enough link bw for this mode\n"); > + return false; > + } > > intel_link_compute_m_n(bpp, lane_count, > adjusted_mode->crtc_clock, > @@ -78,6 +90,28 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, > > } > > +int intel_dp_mst_reset_vcpi(struct intel_encoder *encoder, > + struct drm_connector_state *conn_state, int slots) > +{ > + struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); > + struct drm_dp_mst_topology_mgr *mgr = &intel_mst->primary->dp.mst_mgr; > + struct drm_dp_mst_topology_state *topology_state; > + struct intel_connector *connector = > + to_intel_connector(conn_state->connector); > + int released; > + > + topology_state = drm_atomic_get_mst_topology_state(conn_state->state, mgr); > + if (IS_ERR(topology_state)) > + return PTR_ERR(topology_state); > + > + released = drm_dp_atomic_release_vcpi_slots(topology_state, connector->port); > + > + if (WARN_ON(released != slots)) > + return -EINVAL; > + > + return 0; > +} > + > static void intel_mst_disable_dp(struct intel_encoder *encoder, > struct intel_crtc_state *old_crtc_state, > struct drm_connector_state *old_conn_state) > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 6b02dac..ea2e41e 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1487,6 +1487,9 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector); > /* intel_dp_mst.c */ > int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); > void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port); > +int intel_dp_mst_reset_vcpi(struct intel_encoder *encoder, > + struct drm_connector_state *conn_state, > + int slots); > /* intel_dsi.c */ > void intel_dsi_init(struct drm_i915_private *dev_priv); > > -- > 2.7.4 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx