drm/i915/display/icl: Enable master-slaves in trans port sync
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. v11: * Rebase (Manasi) v10: * in trans sync mode, dont stop link train for tgl (Manasi) v9: Remove update_scanline_offset to rebase on Maarten's patch (Manasi) v8: * Rebase on Maarten's patches (Manasi) v7: * Use ffs(slaves) to get slave crtc (Ville) v6: * Modeset implies active_changed, remove one condition (Maarten) v5: * Fix checkpatch warning (Manasi) v4: * Reuse skl_commit_modeset_enables() hook (Maarten) * Obtain slave crtc and states from master (Maarten) v3: * Rebase on drm-tip (Manasi) v2: * Create a icl_update_crtcs hook (Maarten, Danvet) * This sequence only for CRTCs in trans port sync mode (Maarten) Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191018172725.1338-4-manasi.d.navare@intel.com
This commit is contained in:
Родитель
ba5f1ae95d
Коммит
eadf6f9170
|
@ -3500,7 +3500,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
|
|||
intel_dp_start_link_train(intel_dp);
|
||||
|
||||
/* 7.k */
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
if (!is_trans_port_sync_mode(crtc_state))
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
|
||||
/*
|
||||
* TODO: enable clock gating
|
||||
|
@ -3574,7 +3575,8 @@ static void hsw_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) &&
|
||||
!is_trans_port_sync_mode(crtc_state))
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
|
||||
intel_ddi_enable_fec(encoder, crtc_state);
|
||||
|
|
|
@ -14061,6 +14061,18 @@ static void intel_update_crtc(struct intel_crtc *crtc,
|
|||
intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
|
||||
}
|
||||
|
||||
static struct intel_crtc *intel_get_slave_crtc(const struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(new_crtc_state->base.crtc->dev);
|
||||
enum transcoder slave_transcoder;
|
||||
|
||||
WARN_ON(!is_power_of_2(new_crtc_state->sync_mode_slaves_mask));
|
||||
|
||||
slave_transcoder = ffs(new_crtc_state->sync_mode_slaves_mask) - 1;
|
||||
return intel_get_crtc_for_pipe(dev_priv,
|
||||
(enum pipe)slave_transcoder);
|
||||
}
|
||||
|
||||
static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
|
||||
struct intel_crtc_state *old_crtc_state,
|
||||
struct intel_crtc_state *new_crtc_state,
|
||||
|
@ -14139,6 +14151,113 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
|
|||
}
|
||||
}
|
||||
|
||||
static void intel_crtc_enable_trans_port_sync(struct intel_crtc *crtc,
|
||||
struct intel_atomic_state *state,
|
||||
struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
|
||||
intel_crtc_update_active_timings(new_crtc_state);
|
||||
dev_priv->display.crtc_enable(new_crtc_state, state);
|
||||
intel_crtc_enable_pipe_crc(crtc);
|
||||
}
|
||||
|
||||
static void intel_set_dp_tp_ctl_normal(struct intel_crtc *crtc,
|
||||
struct intel_atomic_state *state)
|
||||
{
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_connector *conn;
|
||||
struct intel_dp *intel_dp;
|
||||
int i;
|
||||
|
||||
for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
|
||||
if (conn_state->crtc == &crtc->base)
|
||||
break;
|
||||
}
|
||||
intel_dp = enc_to_intel_dp(&intel_attached_encoder(conn)->base);
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
}
|
||||
|
||||
static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
|
||||
struct intel_atomic_state *state)
|
||||
{
|
||||
struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
struct intel_plane_state *new_plane_state =
|
||||
intel_atomic_get_new_plane_state(state,
|
||||
to_intel_plane(crtc->base.primary));
|
||||
bool modeset = needs_modeset(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->update_pipe && !new_crtc_state->enable_fbc)
|
||||
intel_fbc_disable(crtc);
|
||||
else if (new_plane_state)
|
||||
intel_fbc_enable(crtc, new_crtc_state, new_plane_state);
|
||||
|
||||
/* Perform vblank evasion around commit operation */
|
||||
intel_pipe_update_start(new_crtc_state);
|
||||
commit_pipe_config(state, old_crtc_state, new_crtc_state);
|
||||
skl_update_planes_on_crtc(state, crtc);
|
||||
intel_pipe_update_end(new_crtc_state);
|
||||
|
||||
/*
|
||||
* We usually enable FIFO underrun interrupts as part of the
|
||||
* CRTC enable sequence during modesets. But when we inherit a
|
||||
* valid pipe configuration from the BIOS we need to take care
|
||||
* of enabling them on the CRTC's first fastset.
|
||||
*/
|
||||
if (new_crtc_state->update_pipe && !modeset &&
|
||||
old_crtc_state->base.mode.private_flags & I915_MODE_FLAG_INHERITED)
|
||||
intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
|
||||
}
|
||||
|
||||
static void intel_update_trans_port_sync_crtcs(struct intel_crtc *crtc,
|
||||
struct intel_atomic_state *state,
|
||||
struct intel_crtc_state *old_crtc_state,
|
||||
struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct intel_crtc *slave_crtc = intel_get_slave_crtc(new_crtc_state);
|
||||
struct intel_crtc_state *new_slave_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, slave_crtc);
|
||||
struct intel_crtc_state *old_slave_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, slave_crtc);
|
||||
|
||||
WARN_ON(!slave_crtc || !new_slave_crtc_state ||
|
||||
!old_slave_crtc_state);
|
||||
|
||||
DRM_DEBUG_KMS("Updating Transcoder Port Sync Master CRTC = %d %s and Slave CRTC %d %s\n",
|
||||
crtc->base.base.id, crtc->base.name, slave_crtc->base.base.id,
|
||||
slave_crtc->base.name);
|
||||
|
||||
/* Enable seq for slave with with DP_TP_CTL left Idle until the
|
||||
* master is ready
|
||||
*/
|
||||
intel_crtc_enable_trans_port_sync(slave_crtc,
|
||||
state,
|
||||
new_slave_crtc_state);
|
||||
|
||||
/* Enable seq for master with with DP_TP_CTL left Idle */
|
||||
intel_crtc_enable_trans_port_sync(crtc,
|
||||
state,
|
||||
new_crtc_state);
|
||||
|
||||
/* Set Slave's DP_TP_CTL to Normal */
|
||||
intel_set_dp_tp_ctl_normal(slave_crtc,
|
||||
state);
|
||||
|
||||
/* Set Master's DP_TP_CTL To Normal */
|
||||
usleep_range(200, 400);
|
||||
intel_set_dp_tp_ctl_normal(crtc,
|
||||
state);
|
||||
|
||||
/* Now do the post crtc enable for all master and slaves */
|
||||
intel_post_crtc_enable_updates(slave_crtc,
|
||||
state);
|
||||
intel_post_crtc_enable_updates(crtc,
|
||||
state);
|
||||
}
|
||||
|
||||
static void skl_commit_modeset_enables(struct intel_atomic_state *state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
|
@ -14172,6 +14291,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
|
|||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
enum pipe pipe = crtc->pipe;
|
||||
bool vbl_wait = false;
|
||||
bool modeset = needs_modeset(new_crtc_state);
|
||||
|
||||
if (updated & BIT(crtc->pipe) || !new_crtc_state->base.active)
|
||||
continue;
|
||||
|
@ -14192,12 +14312,22 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
|
|||
*/
|
||||
if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
|
||||
&old_crtc_state->wm.skl.ddb) &&
|
||||
!new_crtc_state->base.active_changed &&
|
||||
!modeset &&
|
||||
state->wm_results.dirty_pipes != updated)
|
||||
vbl_wait = true;
|
||||
|
||||
intel_update_crtc(crtc, state, old_crtc_state,
|
||||
new_crtc_state);
|
||||
if (modeset && is_trans_port_sync_mode(new_crtc_state)) {
|
||||
if (is_trans_port_sync_master(new_crtc_state))
|
||||
intel_update_trans_port_sync_crtcs(crtc,
|
||||
state,
|
||||
old_crtc_state,
|
||||
new_crtc_state);
|
||||
else
|
||||
continue;
|
||||
} else {
|
||||
intel_update_crtc(crtc, state, old_crtc_state,
|
||||
new_crtc_state);
|
||||
}
|
||||
|
||||
if (vbl_wait)
|
||||
intel_wait_for_vblank(dev_priv, pipe);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <drm/drm_util.h>
|
||||
#include <drm/i915_drm.h>
|
||||
#include "intel_dp_link_training.h"
|
||||
|
||||
enum link_m_n_set;
|
||||
struct dpll;
|
||||
|
@ -54,6 +55,7 @@ struct intel_plane;
|
|||
struct intel_plane_state;
|
||||
struct intel_remapped_info;
|
||||
struct intel_rotation_info;
|
||||
struct intel_crtc_state;
|
||||
|
||||
enum i915_gpio {
|
||||
GPIOA,
|
||||
|
|
Загрузка…
Ссылка в новой задаче