As per the display enable sequence, we need to follow the enable sequence for slaves first with DP_TP_CTL set to Idle and configure the transcoder port sync register to select the corersponding master, then follow the enable sequence for master leaving DP_TP_CTL to idle. At this point the transcoder port sync mode is configured and enabled and the Vblanks of both ports are synchronized so then set DP_TP_CTL for the slave and master to Normal and do post crtc enable updates. Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> Cc: Matt Roper <matthew.d.roper@xxxxxxxxx> Signed-off-by: Manasi Navare <manasi.d.navare@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_ddi.c | 3 +- drivers/gpu/drm/i915/intel_display.c | 122 +++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 24f9106efcc6..0b326b2c274d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3120,7 +3120,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, true); intel_dp_sink_set_fec_ready(intel_dp, crtc_state); intel_dp_start_link_train(intel_dp); - if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) + if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) && + INTEL_GEN(dev_priv) < 11) intel_dp_stop_link_train(intel_dp); intel_ddi_enable_fec(encoder, crtc_state); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4bd23e61c6fd..bd00549a9e00 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13488,6 +13488,7 @@ static void skl_update_crtcs(struct drm_atomic_state *state) for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { bool vbl_wait = false; unsigned int cmask = drm_crtc_mask(crtc); + bool modeset = needs_modeset(new_crtc_state); intel_crtc = to_intel_crtc(crtc); cstate = to_intel_crtc_state(new_crtc_state); @@ -13496,6 +13497,12 @@ static void skl_update_crtcs(struct drm_atomic_state *state) if (updated & cmask || !cstate->base.active) continue; + if (modeset && INTEL_GEN(dev_priv) >= 11) { + DRM_DEBUG_KMS("Pushing the Tiled CRTC %d %s that needs update to separate loop\n", + intel_crtc->base.base.id, intel_crtc->base.name); + continue; + } + if (skl_ddb_allocation_overlaps(&cstate->wm.skl.ddb, entries, INTEL_INFO(dev_priv)->num_pipes, i)) @@ -13526,6 +13533,121 @@ static void skl_update_crtcs(struct drm_atomic_state *state) } } while (progress); + /* Separate loop for updating Slave CRTCs that need modeset. + * We need to loop through all slaves of tiled display first and + * follow enable sequence with DP_TP_CTL left Idle until the master + * is ready. + */ + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + bool modeset = needs_modeset(new_crtc_state); + struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state); + + intel_crtc = to_intel_crtc(crtc); + + if (!pipe_config->base.active) + continue; + if (!modeset) + continue; + if (!pipe_config->master_crtc) + continue; + + update_scanline_offset(pipe_config); + dev_priv->display.crtc_enable(pipe_config, state); + } + /* Now do the display enable sequence for master CRTC */ + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + bool modeset = needs_modeset(new_crtc_state); + struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state); + + intel_crtc = to_intel_crtc(crtc); + + if (!pipe_config->base.active) + continue; + if (!modeset) + continue; + if (pipe_config->master_crtc) + continue; + + update_scanline_offset(pipe_config); + dev_priv->display.crtc_enable(pipe_config, state); + } + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + struct drm_connector_state *conn_state; + struct drm_connector *conn; + bool modeset = needs_modeset(new_crtc_state); + struct intel_dp *intel_dp; + + intel_crtc = to_intel_crtc(crtc); + cstate = to_intel_crtc_state(new_crtc_state); + + if (!cstate->base.active) + continue; + if (!modeset) + continue; + if (!cstate->master_crtc) + continue; + + for_each_new_connector_in_state(state, conn, conn_state, i) { + if (conn_state->crtc == crtc) + break; + } + intel_dp = enc_to_intel_dp(&intel_attached_encoder(conn)->base); + intel_dp_stop_link_train(intel_dp); + } + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + struct drm_connector_state *conn_state; + struct drm_connector *conn; + bool modeset = needs_modeset(new_crtc_state); + struct intel_dp *intel_dp; + + intel_crtc = to_intel_crtc(crtc); + cstate = to_intel_crtc_state(new_crtc_state); + + if (!cstate->base.active) + continue; + if (!modeset) + continue; + if (cstate->master_crtc) + continue; + + /* Wait for 200us before setting the master DP_TP_TCL to Normal */ + usleep_range(200, 400); + for_each_new_connector_in_state(state, conn, conn_state, i) { + if (conn_state->crtc == crtc) + break; + } + intel_dp = enc_to_intel_dp(&intel_attached_encoder(conn)->base); + intel_dp_stop_link_train(intel_dp); + } + /* Now do the post crtc enable for all master and slaves */ + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + bool modeset = needs_modeset(new_crtc_state); + struct intel_plane_state *new_plane_state; + struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state); + + intel_crtc = to_intel_crtc(crtc); + + if (!pipe_config->base.active) + continue; + if (!modeset) + continue; + + new_plane_state = + intel_atomic_get_new_plane_state(to_intel_atomic_state(state), + to_intel_plane(crtc->primary)); + if (pipe_config->update_pipe && !pipe_config->enable_fbc) + intel_fbc_disable(intel_crtc); + else if (new_plane_state) + intel_fbc_enable(intel_crtc, pipe_config, new_plane_state); + + intel_begin_crtc_commit(to_intel_atomic_state(state), intel_crtc); + if (INTEL_GEN(dev_priv) >= 9) + skl_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc); + else + i9xx_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc); + + intel_finish_crtc_commit(to_intel_atomic_state(state), intel_crtc); + } /* If 2nd DBuf slice is no more required disable it */ if (INTEL_GEN(dev_priv) >= 11 && required_slices < hw_enabled_slices) icl_dbuf_slices_update(dev_priv, required_slices); -- 2.19.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx