Commit a621860a authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Plumb crtc_state to link training

Get rid of mode crtc->config usage, and some ad-hoc intel_dp state
usage by plumbing the crtc state all the way down to the link training
code.

Unfortunately we do have to keep some cached state in intel_dp so
that we can do the "does the link need retraining?" checks from
the short hpd handler.

v2: Add intel_crtc_state forward declaration
v3: Don't kill the PHY test code totally since it's
    now in the hotplug work where we can get at the states
v4: Don't resurrect the debug scrambling disable bit (Imre)
    Use intel_dp_mst_is_master_trans() (Imre)
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201001111053.24451-1-ville.syrjala@linux.intel.com
parent 6a41121f
...@@ -1034,7 +1034,8 @@ cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries) ...@@ -1034,7 +1034,8 @@ cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
...@@ -1042,7 +1043,8 @@ icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, ...@@ -1042,7 +1043,8 @@ icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate,
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, icl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
...@@ -1050,12 +1052,13 @@ icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, ...@@ -1050,12 +1052,13 @@ icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate,
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, icl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (rate > 540000) { if (crtc_state->port_clock > 540000) {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
return icl_combo_phy_ddi_translations_edp_hbr3; return icl_combo_phy_ddi_translations_edp_hbr3;
} else if (dev_priv->vbt.edp.low_vswing) { } else if (dev_priv->vbt.edp.low_vswing) {
...@@ -1063,23 +1066,25 @@ icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, ...@@ -1063,23 +1066,25 @@ icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate,
return icl_combo_phy_ddi_translations_edp_hbr2; return icl_combo_phy_ddi_translations_edp_hbr2;
} }
return icl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, icl_get_combo_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
return icl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); return icl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
else if (type == INTEL_OUTPUT_EDP) else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
return icl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); return icl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
else else
return icl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct icl_mg_phy_ddi_buf_trans * static const struct icl_mg_phy_ddi_buf_trans *
icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi); *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
...@@ -1087,10 +1092,11 @@ icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, ...@@ -1087,10 +1092,11 @@ icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate,
} }
static const struct icl_mg_phy_ddi_buf_trans * static const struct icl_mg_phy_ddi_buf_trans *
icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, icl_get_mg_buf_trans_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (rate > 270000) { if (crtc_state->port_clock > 270000) {
*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3); *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3);
return icl_mg_phy_ddi_translations_hbr2_hbr3; return icl_mg_phy_ddi_translations_hbr2_hbr3;
} else { } else {
...@@ -1100,17 +1106,19 @@ icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, ...@@ -1100,17 +1106,19 @@ icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int type, int rate,
} }
static const struct icl_mg_phy_ddi_buf_trans * static const struct icl_mg_phy_ddi_buf_trans *
icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate, icl_get_mg_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
return icl_get_mg_buf_trans_hdmi(encoder, type, rate, n_entries); return icl_get_mg_buf_trans_hdmi(encoder, crtc_state, n_entries);
else else
return icl_get_mg_buf_trans_dp(encoder, type, rate, n_entries); return icl_get_mg_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
...@@ -1118,7 +1126,8 @@ ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, ...@@ -1118,7 +1126,8 @@ ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate,
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp); *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
...@@ -1126,13 +1135,14 @@ ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, ...@@ -1126,13 +1135,14 @@ ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate,
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (dev_priv->vbt.edp.low_vswing) { if (dev_priv->vbt.edp.low_vswing) {
if (rate > 540000) { if (crtc_state->port_clock > 540000) {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
return icl_combo_phy_ddi_translations_edp_hbr3; return icl_combo_phy_ddi_translations_edp_hbr3;
} else { } else {
...@@ -1141,23 +1151,25 @@ ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, ...@@ -1141,23 +1151,25 @@ ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate,
} }
} }
return ehl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, ehl_get_combo_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
return ehl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); return ehl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
else if (type == INTEL_OUTPUT_EDP) else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
return ehl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); return ehl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
else else
return ehl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
...@@ -1165,12 +1177,13 @@ tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, ...@@ -1165,12 +1177,13 @@ tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate,
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (rate > 270000) { if (crtc_state->port_clock > 270000) {
if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) { if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) {
*n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2); *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2);
return tgl_uy_combo_phy_ddi_translations_dp_hbr2; return tgl_uy_combo_phy_ddi_translations_dp_hbr2;
...@@ -1185,13 +1198,14 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, ...@@ -1185,13 +1198,14 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate,
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
if (rate > 540000) { if (crtc_state->port_clock > 540000) {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
return icl_combo_phy_ddi_translations_edp_hbr3; return icl_combo_phy_ddi_translations_edp_hbr3;
} else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) { } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) {
...@@ -1202,23 +1216,25 @@ tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, ...@@ -1202,23 +1216,25 @@ tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate,
return icl_combo_phy_ddi_translations_edp_hbr2; return icl_combo_phy_ddi_translations_edp_hbr2;
} }
return tgl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct cnl_ddi_buf_trans * static const struct cnl_ddi_buf_trans *
tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, tgl_get_combo_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
return tgl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); return tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
else if (type == INTEL_OUTPUT_EDP) else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
return tgl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); return tgl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
else else
return tgl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static const struct tgl_dkl_phy_ddi_buf_trans * static const struct tgl_dkl_phy_ddi_buf_trans *
tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
*n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans); *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
...@@ -1226,10 +1242,11 @@ tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, ...@@ -1226,10 +1242,11 @@ tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate,
} }
static const struct tgl_dkl_phy_ddi_buf_trans * static const struct tgl_dkl_phy_ddi_buf_trans *
tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (rate > 270000) { if (crtc_state->port_clock > 270000) {
*n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans_hbr2); *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans_hbr2);
return tgl_dkl_phy_dp_ddi_trans_hbr2; return tgl_dkl_phy_dp_ddi_trans_hbr2;
} else { } else {
...@@ -1239,16 +1256,18 @@ tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, ...@@ -1239,16 +1256,18 @@ tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int type, int rate,
} }
static const struct tgl_dkl_phy_ddi_buf_trans * static const struct tgl_dkl_phy_ddi_buf_trans *
tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate, tgl_get_dkl_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries) int *n_entries)
{ {
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
return tgl_get_dkl_buf_trans_hdmi(encoder, type, rate, n_entries); return tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, n_entries);
else else
return tgl_get_dkl_buf_trans_dp(encoder, type, rate, n_entries); return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
} }
static int intel_ddi_hdmi_level(struct intel_encoder *encoder) static int intel_ddi_hdmi_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
int n_entries, level, default_entry; int n_entries, level, default_entry;
...@@ -1256,19 +1275,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder) ...@@ -1256,19 +1275,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
if (INTEL_GEN(dev_priv) >= 12) { if (INTEL_GEN(dev_priv) >= 12) {
if (intel_phy_is_combo(dev_priv, phy)) if (intel_phy_is_combo(dev_priv, phy))
tgl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI, tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
0, &n_entries);
else else
tgl_get_dkl_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0, tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries);
&n_entries);
default_entry = n_entries - 1; default_entry = n_entries - 1;
} else if (INTEL_GEN(dev_priv) == 11) { } else if (INTEL_GEN(dev_priv) == 11) {
if (intel_phy_is_combo(dev_priv, phy)) if (intel_phy_is_combo(dev_priv, phy))
icl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI, icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
0, &n_entries);
else else
icl_get_mg_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0, icl_get_mg_buf_trans_hdmi(encoder, crtc_state, &n_entries);
&n_entries);
default_entry = n_entries - 1; default_entry = n_entries - 1;
} else if (IS_CANNONLAKE(dev_priv)) { } else if (IS_CANNONLAKE(dev_priv)) {
cnl_get_buf_trans_hdmi(encoder, &n_entries); cnl_get_buf_trans_hdmi(encoder, &n_entries);
...@@ -1595,14 +1610,15 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, ...@@ -1595,14 +1610,15 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
DP_TP_CTL_ENABLE); DP_TP_CTL_ENABLE);
} }
static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder) static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
intel_dp->DP = dig_port->saved_port_bits | intel_dp->DP = dig_port->saved_port_bits |
DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count);
} }
static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
...@@ -2266,13 +2282,14 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, ...@@ -2266,13 +2282,14 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
} }
static void skl_ddi_set_iboost(struct intel_encoder *encoder, static void skl_ddi_set_iboost(struct intel_encoder *encoder,
int level, enum intel_output_type type) const struct intel_crtc_state *crtc_state,
int level)
{ {
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u8 iboost; u8 iboost;
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
iboost = intel_bios_hdmi_boost_level(encoder); iboost = intel_bios_hdmi_boost_level(encoder);
else else
iboost = intel_bios_dp_boost_level(encoder); iboost = intel_bios_dp_boost_level(encoder);
...@@ -2281,14 +2298,12 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, ...@@ -2281,14 +2298,12 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
const struct ddi_buf_trans *ddi_translations; const struct ddi_buf_trans *ddi_translations;
int n_entries; int n_entries;
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
ddi_translations = intel_ddi_get_buf_trans_hdmi(encoder, &n_entries); ddi_translations = intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
else if (type == INTEL_OUTPUT_EDP) else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
ddi_translations = intel_ddi_get_buf_trans_edp(encoder, ddi_translations = intel_ddi_get_buf_trans_edp(encoder, &n_entries);
&n_entries);
else else
ddi_translations = intel_ddi_get_buf_trans_dp(encoder, ddi_translations = intel_ddi_get_buf_trans_dp(encoder, &n_entries);
&n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return; return;
...@@ -2311,16 +2326,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, ...@@ -2311,16 +2326,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
} }
static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
int level, enum intel_output_type type) const struct intel_crtc_state *crtc_state,
int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
const struct bxt_ddi_buf_trans *ddi_translations; const struct bxt_ddi_buf_trans *ddi_translations;
enum port port = encoder->port; enum port port = encoder->port;
int n_entries; int n_entries;
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
ddi_translations = bxt_get_buf_trans_hdmi(encoder, &n_entries); ddi_translations = bxt_get_buf_trans_hdmi(encoder, &n_entries);
else if (type == INTEL_OUTPUT_EDP) else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
ddi_translations = bxt_get_buf_trans_edp(encoder, &n_entries); ddi_translations = bxt_get_buf_trans_edp(encoder, &n_entries);
else else
ddi_translations = bxt_get_buf_trans_dp(encoder, &n_entries); ddi_translations = bxt_get_buf_trans_dp(encoder, &n_entries);
...@@ -2337,7 +2353,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2337,7 +2353,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
ddi_translations[level].deemphasis); ddi_translations[level].deemphasis);
} }
static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp) static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
...@@ -2347,33 +2364,28 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp) ...@@ -2347,33 +2364,28 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
if (INTEL_GEN(dev_priv) >= 12) { if (INTEL_GEN(dev_priv) >= 12) {
if (intel_phy_is_combo(dev_priv, phy)) if (intel_phy_is_combo(dev_priv, phy))
tgl_get_combo_buf_trans(encoder, encoder->type, tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
intel_dp->link_rate, &n_entries);
else else
tgl_get_dkl_buf_trans(encoder, encoder->type, tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
intel_dp->link_rate, &n_entries);
} else if (INTEL_GEN(dev_priv) == 11) { } else if (INTEL_GEN(dev_priv) == 11) {
if (IS_ELKHARTLAKE(dev_priv)) if (IS_ELKHARTLAKE(dev_priv))
ehl_get_combo_buf_trans(encoder, encoder->type, ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
intel_dp->link_rate, &n_entries);
else if (intel_phy_is_combo(dev_priv, phy)) else if (intel_phy_is_combo(dev_priv, phy))
icl_get_combo_buf_trans(encoder, encoder->type, icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
intel_dp->link_rate, &n_entries);
else else
icl_get_mg_buf_trans(encoder, encoder->type, icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
intel_dp->link_rate, &n_entries);
} else if (IS_CANNONLAKE(dev_priv)) { } else if (IS_CANNONLAKE(dev_priv)) {
if (encoder->type == INTEL_OUTPUT_EDP) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
cnl_get_buf_trans_edp(encoder, &n_entries); cnl_get_buf_trans_edp(encoder, &n_entries);
else else
cnl_get_buf_trans_dp(encoder, &n_entries); cnl_get_buf_trans_dp(encoder, &n_entries);
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEN9_LP(dev_priv)) {
if (encoder->type == INTEL_OUTPUT_EDP) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
bxt_get_buf_trans_edp(encoder, &n_entries); bxt_get_buf_trans_edp(encoder, &n_entries);
else else
bxt_get_buf_trans_dp(encoder, &n_entries); bxt_get_buf_trans_dp(encoder, &n_entries);
} else { } else {
if (encoder->type == INTEL_OUTPUT_EDP) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
intel_ddi_get_buf_trans_edp(encoder, &n_entries); intel_ddi_get_buf_trans_edp(encoder, &n_entries);
else else
intel_ddi_get_buf_trans_dp(encoder, &n_entries); intel_ddi_get_buf_trans_dp(encoder, &n_entries);
...@@ -2400,7 +2412,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp) ...@@ -2400,7 +2412,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
} }
static void cnl_ddi_vswing_program(struct intel_encoder *encoder, static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
int level, enum intel_output_type type) const struct intel_crtc_state *crtc_state,
int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
const struct cnl_ddi_buf_trans *ddi_translations; const struct cnl_ddi_buf_trans *ddi_translations;
...@@ -2408,9 +2421,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder, ...@@ -2408,9 +2421,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
int n_entries, ln; int n_entries, ln;
u32 val; u32 val;
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
ddi_translations = cnl_get_buf_trans_hdmi(encoder, &n_entries); ddi_translations = cnl_get_buf_trans_hdmi(encoder, &n_entries);
else if (type == INTEL_OUTPUT_EDP) else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
ddi_translations = cnl_get_buf_trans_edp(encoder, &n_entries); ddi_translations = cnl_get_buf_trans_edp(encoder, &n_entries);
else else
ddi_translations = cnl_get_buf_trans_dp(encoder, &n_entries); ddi_translations = cnl_get_buf_trans_dp(encoder, &n_entries);
...@@ -2464,22 +2477,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder, ...@@ -2464,22 +2477,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
} }
static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
int level, enum intel_output_type type) const struct intel_crtc_state *crtc_state,
int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port; enum port port = encoder->port;
int width, rate, ln; int width, rate, ln;
u32 val; u32 val;
if (type == INTEL_OUTPUT_HDMI) { width = crtc_state->lane_count;
width = 4; rate = crtc_state->port_clock;
rate = 0; /* Rate is always < than 6GHz for HDMI */
} else {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
width = intel_dp->lane_count;
rate = intel_dp->link_rate;
}
/* /*
* 1. If port type is eDP or DP, * 1. If port type is eDP or DP,
...@@ -2487,10 +2494,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2487,10 +2494,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
* else clear to 0b. * else clear to 0b.
*/ */
val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port)); val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port));
if (type != INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val |= COMMON_KEEPER_EN;
else
val &= ~COMMON_KEEPER_EN; val &= ~COMMON_KEEPER_EN;
else
val |= COMMON_KEEPER_EN;
intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val); intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val);
/* 2. Program loadgen select */ /* 2. Program loadgen select */
...@@ -2522,7 +2529,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2522,7 +2529,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val); intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
/* 5. Program swing and de-emphasis */ /* 5. Program swing and de-emphasis */
cnl_ddi_vswing_program(encoder, level, type); cnl_ddi_vswing_program(encoder, crtc_state, level);
/* 6. Set training enable to trigger update */ /* 6. Set training enable to trigger update */
val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port)); val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
...@@ -2531,23 +2538,21 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2531,23 +2538,21 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
} }
static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
u32 level, int type, int rate) const struct intel_crtc_state *crtc_state,
int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
const struct cnl_ddi_buf_trans *ddi_translations;
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
const struct cnl_ddi_buf_trans *ddi_translations = NULL; int n_entries, ln;
u32 n_entries, val; u32 val;
int ln;
if (INTEL_GEN(dev_priv) >= 12) if (INTEL_GEN(dev_priv) >= 12)
ddi_translations = tgl_get_combo_buf_trans(encoder, type, rate, ddi_translations = tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
&n_entries);
else if (IS_ELKHARTLAKE(dev_priv)) else if (IS_ELKHARTLAKE(dev_priv))
ddi_translations = ehl_get_combo_buf_trans(encoder, type, rate, ddi_translations = ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
&n_entries);
else else
ddi_translations = icl_get_combo_buf_trans(encoder, type, rate, ddi_translations = icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
&n_entries);
if (!ddi_translations) if (!ddi_translations)
return; return;
...@@ -2558,7 +2563,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, ...@@ -2558,7 +2563,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
level = n_entries - 1; level = n_entries - 1;
} }
if (type == INTEL_OUTPUT_EDP) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED;
...@@ -2606,25 +2611,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, ...@@ -2606,25 +2611,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
} }
static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
u32 level, const struct intel_crtc_state *crtc_state,
enum intel_output_type type) int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
int width = 0; int width, rate, ln;
int rate = 0;
u32 val; u32 val;
int ln = 0;
if (type == INTEL_OUTPUT_HDMI) {
width = 4;
/* Rate is always < than 6GHz for HDMI */
} else {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
width = intel_dp->lane_count; width = crtc_state->lane_count;
rate = intel_dp->link_rate; rate = crtc_state->port_clock;
}
/* /*
* 1. If port type is eDP or DP, * 1. If port type is eDP or DP,
...@@ -2632,7 +2628,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2632,7 +2628,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
* else clear to 0b. * else clear to 0b.
*/ */
val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy)); val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy));
if (type == INTEL_OUTPUT_HDMI) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val &= ~COMMON_KEEPER_EN; val &= ~COMMON_KEEPER_EN;
else else
val |= COMMON_KEEPER_EN; val |= COMMON_KEEPER_EN;
...@@ -2667,7 +2663,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2667,7 +2663,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);
/* 5. Program swing and de-emphasis */ /* 5. Program swing and de-emphasis */
icl_ddi_combo_vswing_program(encoder, level, type, rate); icl_ddi_combo_vswing_program(encoder, crtc_state, level);
/* 6. Set training enable to trigger update */ /* 6. Set training enable to trigger update */
val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
...@@ -2676,23 +2672,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2676,23 +2672,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
} }
static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
int link_clock, u32 level, const struct intel_crtc_state *crtc_state,
enum intel_output_type type) int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
const struct icl_mg_phy_ddi_buf_trans *ddi_translations; const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
u32 n_entries, val; int n_entries, ln;
int ln, rate = 0; u32 val;
if (type != INTEL_OUTPUT_HDMI) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
rate = intel_dp->link_rate;
}
ddi_translations = icl_get_mg_buf_trans(encoder, type, rate, ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
&n_entries);
/* The table does not have values for level 3 and level 9. */ /* The table does not have values for level 3 and level 9. */
if (level >= n_entries || level == 3 || level == 9) { if (level >= n_entries || level == 3 || level == 9) {
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
...@@ -2759,7 +2748,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2759,7 +2748,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
*/ */
for (ln = 0; ln < 2; ln++) { for (ln = 0; ln < 2; ln++) {
val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port)); val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port));
if (link_clock < 300000) if (crtc_state->port_clock < 300000)
val |= CFG_LOW_RATE_LKREN_EN; val |= CFG_LOW_RATE_LKREN_EN;
else else
val &= ~CFG_LOW_RATE_LKREN_EN; val &= ~CFG_LOW_RATE_LKREN_EN;
...@@ -2770,7 +2759,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2770,7 +2759,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
for (ln = 0; ln < 2; ln++) { for (ln = 0; ln < 2; ln++) {
val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port)); val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port));
val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK; val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
if (link_clock <= 500000) { if (crtc_state->port_clock <= 500000) {
val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN; val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
} else { } else {
val |= CFG_AMI_CK_DIV_OVERRIDE_EN | val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
...@@ -2780,7 +2769,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2780,7 +2769,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port)); val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port));
val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK; val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
if (link_clock <= 500000) { if (crtc_state->port_clock <= 500000) {
val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN; val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
} else { } else {
val |= CFG_AMI_CK_DIV_OVERRIDE_EN | val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
...@@ -2806,38 +2795,30 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, ...@@ -2806,38 +2795,30 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
} }
static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
int link_clock, const struct intel_crtc_state *crtc_state,
u32 level, int level)
enum intel_output_type type)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
if (intel_phy_is_combo(dev_priv, phy)) if (intel_phy_is_combo(dev_priv, phy))
icl_combo_phy_ddi_vswing_sequence(encoder, level, type); icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
else else
icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level, icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level);
type);
} }
static void static void
tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock, tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
u32 level, enum intel_output_type type) const struct intel_crtc_state *crtc_state,
int level)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations; const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
u32 n_entries, val, ln, dpcnt_mask, dpcnt_val; u32 val, dpcnt_mask, dpcnt_val;
int rate = 0; int n_entries, ln;
if (type != INTEL_OUTPUT_HDMI) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
rate = intel_dp->link_rate;
}
ddi_translations = tgl_get_dkl_buf_trans(encoder, encoder->type, rate, ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
&n_entries);
if (level >= n_entries) if (level >= n_entries)
level = n_entries - 1; level = n_entries - 1;
...@@ -2873,20 +2854,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock, ...@@ -2873,20 +2854,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
} }
static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder, static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
int link_clock, const struct intel_crtc_state *crtc_state,
u32 level, int level)
enum intel_output_type type)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
if (intel_phy_is_combo(dev_priv, phy)) if (intel_phy_is_combo(dev_priv, phy))
icl_combo_phy_ddi_vswing_sequence(encoder, level, type); icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
else else
tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type); tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level);
} }
static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels) static int translate_signal_level(struct intel_dp *intel_dp,
u8 signal_levels)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i; int i;
...@@ -2903,55 +2884,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels) ...@@ -2903,55 +2884,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
return 0; return 0;
} }
static u32 intel_ddi_dp_level(struct intel_dp *intel_dp) static int intel_ddi_dp_level(struct intel_dp *intel_dp)
{ {
u8 train_set = intel_dp->train_set[0]; u8 train_set = intel_dp->train_set[0];
int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
DP_TRAIN_PRE_EMPHASIS_MASK); DP_TRAIN_PRE_EMPHASIS_MASK);
return translate_signal_level(intel_dp, signal_levels); return translate_signal_level(intel_dp, signal_levels);
} }
static void static void
tgl_set_signal_levels(struct intel_dp *intel_dp) tgl_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp); int level = intel_ddi_dp_level(intel_dp);
tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate, tgl_ddi_vswing_sequence(encoder, crtc_state, level);
level, encoder->type);
} }
static void static void
icl_set_signal_levels(struct intel_dp *intel_dp) icl_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp); int level = intel_ddi_dp_level(intel_dp);
icl_ddi_vswing_sequence(encoder, intel_dp->link_rate, icl_ddi_vswing_sequence(encoder, crtc_state, level);
level, encoder->type);
} }
static void static void
cnl_set_signal_levels(struct intel_dp *intel_dp) cnl_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp); int level = intel_ddi_dp_level(intel_dp);
cnl_ddi_vswing_sequence(encoder, level, encoder->type); cnl_ddi_vswing_sequence(encoder, crtc_state, level);
} }
static void static void
bxt_set_signal_levels(struct intel_dp *intel_dp) bxt_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp); int level = intel_ddi_dp_level(intel_dp);
bxt_ddi_vswing_sequence(encoder, level, encoder->type); bxt_ddi_vswing_sequence(encoder, crtc_state, level);
} }
static void static void
hsw_set_signal_levels(struct intel_dp *intel_dp) hsw_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
...@@ -2968,7 +2952,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp) ...@@ -2968,7 +2952,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
intel_dp->DP |= signal_levels; intel_dp->DP |= signal_levels;
if (IS_GEN9_BC(dev_priv)) if (IS_GEN9_BC(dev_priv))
skl_ddi_set_iboost(encoder, level, encoder->type); skl_ddi_set_iboost(encoder, crtc_state, level);
intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
...@@ -3375,8 +3359,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3375,8 +3359,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
int level = intel_ddi_dp_level(intel_dp); int level = intel_ddi_dp_level(intel_dp);
enum transcoder transcoder = crtc_state->cpu_transcoder; enum transcoder transcoder = crtc_state->cpu_transcoder;
intel_dp_set_link_params(intel_dp, crtc_state->port_clock, intel_dp_set_link_params(intel_dp,
crtc_state->lane_count, is_mst); crtc_state->port_clock,
crtc_state->lane_count);
intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder); intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder); intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
...@@ -3448,8 +3433,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3448,8 +3433,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
*/ */
/* 7.e Configure voltage swing and related IO settings */ /* 7.e Configure voltage swing and related IO settings */
tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level, tgl_ddi_vswing_sequence(encoder, crtc_state, level);
encoder->type);
/* /*
* 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
...@@ -3472,7 +3456,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3472,7 +3456,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* We only configure what the register value will be here. Actual * We only configure what the register value will be here. Actual
* enabling happens during link training farther down. * enabling happens during link training farther down.
*/ */
intel_ddi_init_dp_buf_reg(encoder); intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst) if (!is_mst)
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
...@@ -3492,11 +3476,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3492,11 +3476,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us) * (timeout after 800 us)
*/ */
intel_dp_start_link_train(intel_dp); intel_dp_start_link_train(intel_dp, crtc_state);
/* 7.k Set DP_TP_CTL link training to Normal */ /* 7.k Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state)) if (!is_trans_port_sync_mode(crtc_state))
intel_dp_stop_link_train(intel_dp); intel_dp_stop_link_train(intel_dp, crtc_state);
/* 7.l Configure and enable FEC if needed */ /* 7.l Configure and enable FEC if needed */
intel_ddi_enable_fec(encoder, crtc_state); intel_ddi_enable_fec(encoder, crtc_state);
...@@ -3522,8 +3506,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3522,8 +3506,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
else else
drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A); drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A);
intel_dp_set_link_params(intel_dp, crtc_state->port_clock, intel_dp_set_link_params(intel_dp,
crtc_state->lane_count, is_mst); crtc_state->port_clock,
crtc_state->lane_count);
intel_edp_panel_on(intel_dp); intel_edp_panel_on(intel_dp);
...@@ -3537,12 +3522,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3537,12 +3522,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
icl_program_mg_dp_mode(dig_port, crtc_state); icl_program_mg_dp_mode(dig_port, crtc_state);
if (INTEL_GEN(dev_priv) >= 11) if (INTEL_GEN(dev_priv) >= 11)
icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, icl_ddi_vswing_sequence(encoder, crtc_state, level);
level, encoder->type);
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
cnl_ddi_vswing_sequence(encoder, level, encoder->type); cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEN9_LP(dev_priv))
bxt_ddi_vswing_sequence(encoder, level, encoder->type); bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else else
intel_prepare_dp_ddi_buffers(encoder, crtc_state); intel_prepare_dp_ddi_buffers(encoder, crtc_state);
...@@ -3555,17 +3539,17 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -3555,17 +3539,17 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
lane_reversal); lane_reversal);
} }
intel_ddi_init_dp_buf_reg(encoder); intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst) if (!is_mst)
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_configure_protocol_converter(intel_dp); intel_dp_configure_protocol_converter(intel_dp);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
true); true);
intel_dp_sink_set_fec_ready(intel_dp, crtc_state); intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
intel_dp_start_link_train(intel_dp); intel_dp_start_link_train(intel_dp, crtc_state);
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)) !is_trans_port_sync_mode(crtc_state))
intel_dp_stop_link_train(intel_dp); intel_dp_stop_link_train(intel_dp, crtc_state);
intel_ddi_enable_fec(encoder, crtc_state); intel_ddi_enable_fec(encoder, crtc_state);
...@@ -3605,7 +3589,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, ...@@ -3605,7 +3589,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_hdmi *intel_hdmi = &dig_port->hdmi; struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
int level = intel_ddi_hdmi_level(encoder); int level = intel_ddi_hdmi_level(encoder, crtc_state);
intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
intel_ddi_clk_select(encoder, crtc_state); intel_ddi_clk_select(encoder, crtc_state);
...@@ -3615,20 +3599,18 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, ...@@ -3615,20 +3599,18 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
icl_program_mg_dp_mode(dig_port, crtc_state); icl_program_mg_dp_mode(dig_port, crtc_state);
if (INTEL_GEN(dev_priv) >= 12) if (INTEL_GEN(dev_priv) >= 12)
tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, tgl_ddi_vswing_sequence(encoder, crtc_state, level);
level, INTEL_OUTPUT_HDMI);
else if (INTEL_GEN(dev_priv) == 11) else if (INTEL_GEN(dev_priv) == 11)
icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, icl_ddi_vswing_sequence(encoder, crtc_state, level);
level, INTEL_OUTPUT_HDMI);
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEN9_LP(dev_priv))
bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else else
intel_prepare_hdmi_ddi_buffers(encoder, level); intel_prepare_hdmi_ddi_buffers(encoder, level);
if (IS_GEN9_BC(dev_priv)) if (IS_GEN9_BC(dev_priv))
skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI); skl_ddi_set_iboost(encoder, crtc_state, level);
intel_ddi_enable_pipe_clock(encoder, crtc_state); intel_ddi_enable_pipe_clock(encoder, crtc_state);
...@@ -3918,12 +3900,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state, ...@@ -3918,12 +3900,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
crtc_state->cpu_transcoder) crtc_state->cpu_transcoder)
continue; continue;
intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder)); intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder),
slave_crtc_state);
} }
usleep_range(200, 400); usleep_range(200, 400);
intel_dp_stop_link_train(enc_to_intel_dp(encoder)); intel_dp_stop_link_train(enc_to_intel_dp(encoder),
crtc_state);
} }
static void intel_enable_ddi_dp(struct intel_atomic_state *state, static void intel_enable_ddi_dp(struct intel_atomic_state *state,
...@@ -3936,7 +3920,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, ...@@ -3936,7 +3920,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
enum port port = encoder->port; enum port port = encoder->port;
if (port == PORT_A && INTEL_GEN(dev_priv) < 9) if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
intel_dp_stop_link_train(intel_dp); intel_dp_stop_link_train(intel_dp, crtc_state);
intel_edp_backlight_on(crtc_state, conn_state); intel_edp_backlight_on(crtc_state, conn_state);
intel_psr_enable(intel_dp, crtc_state, conn_state); intel_psr_enable(intel_dp, crtc_state, conn_state);
...@@ -4197,7 +4181,8 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, ...@@ -4197,7 +4181,8 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
crtc_state->lane_lat_optim_mask); crtc_state->lane_lat_optim_mask);
} }
static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
...@@ -4225,9 +4210,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) ...@@ -4225,9 +4210,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
} }
dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1;
if (intel_dp->link_mst) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
dp_tp_ctl |= DP_TP_CTL_MODE_MST; dp_tp_ctl |= DP_TP_CTL_MODE_MST;
else { } else {
dp_tp_ctl |= DP_TP_CTL_MODE_SST; dp_tp_ctl |= DP_TP_CTL_MODE_SST;
if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
...@@ -4243,6 +4228,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) ...@@ -4243,6 +4228,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
} }
static void intel_ddi_set_link_train(struct intel_dp *intel_dp, static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat) u8 dp_train_pat)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
...@@ -4273,7 +4259,8 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, ...@@ -4273,7 +4259,8 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp); intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp);
} }
static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp) static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
......
...@@ -41,8 +41,10 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, ...@@ -41,8 +41,10 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
bool state); bool state);
void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
struct intel_crtc_state *crtc_state); struct intel_crtc_state *crtc_state);
u32 bxt_signal_levels(struct intel_dp *intel_dp); u32 bxt_signal_levels(struct intel_dp *intel_dp,
u32 ddi_signal_levels(struct intel_dp *intel_dp); const struct intel_crtc_state *crtc_state);
u32 ddi_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
enum transcoder cpu_transcoder, enum transcoder cpu_transcoder,
bool enable); bool enable);
......
...@@ -1273,7 +1273,6 @@ struct intel_dp { ...@@ -1273,7 +1273,6 @@ struct intel_dp {
int link_rate; int link_rate;
u8 lane_count; u8 lane_count;
u8 sink_count; u8 sink_count;
bool link_mst;
bool link_trained; bool link_trained;
bool has_hdmi_sink; bool has_hdmi_sink;
bool has_audio; bool has_audio;
...@@ -1366,13 +1365,19 @@ struct intel_dp { ...@@ -1366,13 +1365,19 @@ struct intel_dp {
i915_reg_t (*aux_ch_data_reg)(struct intel_dp *dp, int index); i915_reg_t (*aux_ch_data_reg)(struct intel_dp *dp, int index);
/* This is called before a link training is starterd */ /* This is called before a link training is starterd */
void (*prepare_link_retrain)(struct intel_dp *intel_dp); void (*prepare_link_retrain)(struct intel_dp *intel_dp,
void (*set_link_train)(struct intel_dp *intel_dp, u8 dp_train_pat); const struct intel_crtc_state *crtc_state);
void (*set_idle_link_train)(struct intel_dp *intel_dp); void (*set_link_train)(struct intel_dp *intel_dp,
void (*set_signal_levels)(struct intel_dp *intel_dp); const struct intel_crtc_state *crtc_state,
u8 dp_train_pat);
void (*set_idle_link_train)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void (*set_signal_levels)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
u8 (*preemph_max)(struct intel_dp *intel_dp); u8 (*preemph_max)(struct intel_dp *intel_dp);
u8 (*voltage_max)(struct intel_dp *intel_dp); u8 (*voltage_max)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
/* Displayport compliance testing */ /* Displayport compliance testing */
struct intel_dp_compliance compliance; struct intel_dp_compliance compliance;
......
...@@ -2799,13 +2799,11 @@ intel_dp_compute_config(struct intel_encoder *encoder, ...@@ -2799,13 +2799,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
} }
void intel_dp_set_link_params(struct intel_dp *intel_dp, void intel_dp_set_link_params(struct intel_dp *intel_dp,
int link_rate, u8 lane_count, int link_rate, int lane_count)
bool link_mst)
{ {
intel_dp->link_trained = false; intel_dp->link_trained = false;
intel_dp->link_rate = link_rate; intel_dp->link_rate = link_rate;
intel_dp->lane_count = lane_count; intel_dp->lane_count = lane_count;
intel_dp->link_mst = link_mst;
} }
static void intel_dp_prepare(struct intel_encoder *encoder, static void intel_dp_prepare(struct intel_encoder *encoder,
...@@ -2817,10 +2815,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder, ...@@ -2817,10 +2815,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
intel_dp_set_link_params(intel_dp, pipe_config->port_clock, intel_dp_set_link_params(intel_dp,
pipe_config->lane_count, pipe_config->port_clock,
intel_crtc_has_type(pipe_config, pipe_config->lane_count);
INTEL_OUTPUT_DP_MST));
/* /*
* There are four kinds of DP registers: * There are four kinds of DP registers:
...@@ -3791,6 +3788,7 @@ static void chv_post_disable_dp(struct intel_atomic_state *state, ...@@ -3791,6 +3788,7 @@ static void chv_post_disable_dp(struct intel_atomic_state *state,
static void static void
cpt_set_link_train(struct intel_dp *intel_dp, cpt_set_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat) u8 dp_train_pat)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
...@@ -3821,6 +3819,7 @@ cpt_set_link_train(struct intel_dp *intel_dp, ...@@ -3821,6 +3819,7 @@ cpt_set_link_train(struct intel_dp *intel_dp,
static void static void
g4x_set_link_train(struct intel_dp *intel_dp, g4x_set_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat) u8 dp_train_pat)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
...@@ -3856,7 +3855,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp, ...@@ -3856,7 +3855,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
/* enable with pattern 1 (as per spec) */ /* enable with pattern 1 (as per spec) */
intel_dp_program_link_training_pattern(intel_dp, DP_TRAINING_PATTERN_1); intel_dp_program_link_training_pattern(intel_dp, crtc_state,
DP_TRAINING_PATTERN_1);
/* /*
* Magic for VLV/CHV. We _must_ first set up the register * Magic for VLV/CHV. We _must_ first set up the register
...@@ -3947,8 +3947,8 @@ static void intel_enable_dp(struct intel_atomic_state *state, ...@@ -3947,8 +3947,8 @@ static void intel_enable_dp(struct intel_atomic_state *state,
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_configure_protocol_converter(intel_dp); intel_dp_configure_protocol_converter(intel_dp);
intel_dp_start_link_train(intel_dp); intel_dp_start_link_train(intel_dp, pipe_config);
intel_dp_stop_link_train(intel_dp); intel_dp_stop_link_train(intel_dp, pipe_config);
if (pipe_config->has_audio) { if (pipe_config->has_audio) {
drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n", drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n",
...@@ -4157,12 +4157,14 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU ...@@ -4157,12 +4157,14 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU
DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE; DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
} }
static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp) static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
} }
static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp) static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
} }
...@@ -4177,7 +4179,8 @@ static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp) ...@@ -4177,7 +4179,8 @@ static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp)
return DP_TRAIN_PRE_EMPH_LEVEL_3; return DP_TRAIN_PRE_EMPH_LEVEL_3;
} }
static void vlv_set_signal_levels(struct intel_dp *intel_dp) static void vlv_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
unsigned long demph_reg_value, preemph_reg_value, unsigned long demph_reg_value, preemph_reg_value,
...@@ -4257,11 +4260,13 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp) ...@@ -4257,11 +4260,13 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp)
return; return;
} }
vlv_set_phy_signal_level(encoder, demph_reg_value, preemph_reg_value, vlv_set_phy_signal_level(encoder, crtc_state,
demph_reg_value, preemph_reg_value,
uniqtranscale_reg_value, 0); uniqtranscale_reg_value, 0);
} }
static void chv_set_signal_levels(struct intel_dp *intel_dp) static void chv_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
u32 deemph_reg_value, margin_reg_value; u32 deemph_reg_value, margin_reg_value;
...@@ -4338,8 +4343,9 @@ static void chv_set_signal_levels(struct intel_dp *intel_dp) ...@@ -4338,8 +4343,9 @@ static void chv_set_signal_levels(struct intel_dp *intel_dp)
return; return;
} }
chv_set_phy_signal_level(encoder, deemph_reg_value, chv_set_phy_signal_level(encoder, crtc_state,
margin_reg_value, uniq_trans_scale); deemph_reg_value, margin_reg_value,
uniq_trans_scale);
} }
static u32 g4x_signal_levels(u8 train_set) static u32 g4x_signal_levels(u8 train_set)
...@@ -4380,7 +4386,8 @@ static u32 g4x_signal_levels(u8 train_set) ...@@ -4380,7 +4386,8 @@ static u32 g4x_signal_levels(u8 train_set)
} }
static void static void
g4x_set_signal_levels(struct intel_dp *intel_dp) g4x_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u8 train_set = intel_dp->train_set[0]; u8 train_set = intel_dp->train_set[0];
...@@ -4427,7 +4434,8 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set) ...@@ -4427,7 +4434,8 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set)
} }
static void static void
snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp) snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u8 train_set = intel_dp->train_set[0]; u8 train_set = intel_dp->train_set[0];
...@@ -4478,7 +4486,8 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set) ...@@ -4478,7 +4486,8 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set)
} }
static void static void
ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp) ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u8 train_set = intel_dp->train_set[0]; u8 train_set = intel_dp->train_set[0];
...@@ -4496,7 +4505,8 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp) ...@@ -4496,7 +4505,8 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
intel_de_posting_read(dev_priv, intel_dp->output_reg); intel_de_posting_read(dev_priv, intel_dp->output_reg);
} }
void intel_dp_set_signal_levels(struct intel_dp *intel_dp) void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u8 train_set = intel_dp->train_set[0]; u8 train_set = intel_dp->train_set[0];
...@@ -4510,11 +4520,12 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp) ...@@ -4510,11 +4520,12 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp)
train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
" (max)" : ""); " (max)" : "");
intel_dp->set_signal_levels(intel_dp); intel_dp->set_signal_levels(intel_dp, crtc_state);
} }
void void
intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat) u8 dp_train_pat)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
...@@ -4525,13 +4536,14 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, ...@@ -4525,13 +4536,14 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
"Using DP training pattern TPS%d\n", "Using DP training pattern TPS%d\n",
dp_train_pat & train_pat_mask); dp_train_pat & train_pat_mask);
intel_dp->set_link_train(intel_dp, dp_train_pat); intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat);
} }
void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) void intel_dp_set_idle_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
if (intel_dp->set_idle_link_train) if (intel_dp->set_idle_link_train)
intel_dp->set_idle_link_train(intel_dp); intel_dp->set_idle_link_train(intel_dp, crtc_state);
} }
static void static void
...@@ -5424,14 +5436,14 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) ...@@ -5424,14 +5436,14 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
return test_result; return test_result;
} }
static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
to_i915(dp_to_dig_port(intel_dp)->base.base.dev); to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_dp_phy_test_params *data = struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest; &intel_dp->compliance.test_data.phytest;
struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
u32 pattern_val; u32 pattern_val;
...@@ -5491,7 +5503,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) ...@@ -5491,7 +5503,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
} }
static void static void
intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp) intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev; struct drm_device *dev = dig_port->base.base.dev;
...@@ -5517,7 +5530,8 @@ intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp) ...@@ -5517,7 +5530,8 @@ intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
} }
static void static void
intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt) intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev; struct drm_device *dev = dig_port->base.base.dev;
...@@ -5543,7 +5557,8 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt) ...@@ -5543,7 +5557,8 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
trans_ddi_func_ctl_value); trans_ddi_func_ctl_value);
} }
static void intel_dp_process_phy_request(struct intel_dp *intel_dp) static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_dp_phy_test_params *data = struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest; &intel_dp->compliance.test_data.phytest;
...@@ -5555,15 +5570,15 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp) ...@@ -5555,15 +5570,15 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp)
} }
/* retrieve vswing & pre-emphasis setting */ /* retrieve vswing & pre-emphasis setting */
intel_dp_get_adjust_train(intel_dp, link_status); intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
intel_dp_autotest_phy_ddi_disable(intel_dp); intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
intel_dp_set_signal_levels(intel_dp); intel_dp_set_signal_levels(intel_dp, crtc_state);
intel_dp_phy_pattern_update(intel_dp); intel_dp_phy_pattern_update(intel_dp, crtc_state);
intel_dp_autotest_phy_ddi_enable(intel_dp, data->num_lanes); intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state);
drm_dp_set_phy_test_pattern(&intel_dp->aux, data, drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
link_status[DP_DPCD_REV]); link_status[DP_DPCD_REV]);
...@@ -5719,6 +5734,10 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) ...@@ -5719,6 +5734,10 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
/* /*
* Validate the cached values of intel_dp->link_rate and * Validate the cached values of intel_dp->link_rate and
* intel_dp->lane_count before attempting to retrain. * intel_dp->lane_count before attempting to retrain.
*
* FIXME would be nice to user the crtc state here, but since
* we need to call this from the short HPD handler that seems
* a bit hard.
*/ */
if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate, if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate,
intel_dp->lane_count)) intel_dp->lane_count))
...@@ -5852,8 +5871,20 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, ...@@ -5852,8 +5871,20 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), false); intel_crtc_pch_transcoder(crtc), false);
} }
intel_dp_start_link_train(intel_dp); for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
intel_dp_stop_link_train(intel_dp); const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
/* retrain on the MST master transcoder */
if (INTEL_GEN(dev_priv) >= 12 &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
!intel_dp_mst_is_master_trans(crtc_state))
continue;
intel_dp_start_link_train(intel_dp, crtc_state);
intel_dp_stop_link_train(intel_dp, crtc_state);
break;
}
for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
const struct intel_crtc_state *crtc_state = const struct intel_crtc_state *crtc_state =
...@@ -5923,6 +5954,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, ...@@ -5923,6 +5954,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder,
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *crtc;
u32 crtc_mask; u32 crtc_mask;
int ret; int ret;
...@@ -5940,7 +5972,20 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, ...@@ -5940,7 +5972,20 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder,
drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n",
encoder->base.base.id, encoder->base.name); encoder->base.base.id, encoder->base.name);
intel_dp_process_phy_request(intel_dp);
for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
/* test on the MST master transcoder */
if (INTEL_GEN(dev_priv) >= 12 &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
!intel_dp_mst_is_master_trans(crtc_state))
continue;
intel_dp_process_phy_request(intel_dp, crtc_state);
break;
}
return 0; return 0;
} }
......
...@@ -45,8 +45,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg, ...@@ -45,8 +45,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg,
bool intel_dp_init_connector(struct intel_digital_port *dig_port, bool intel_dp_init_connector(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector); struct intel_connector *intel_connector);
void intel_dp_set_link_params(struct intel_dp *intel_dp, void intel_dp_set_link_params(struct intel_dp *intel_dp,
int link_rate, u8 lane_count, int link_rate, int lane_count);
bool link_mst);
int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
int link_rate, u8 lane_count); int link_rate, u8 lane_count);
int intel_dp_retrain_link(struct intel_encoder *encoder, int intel_dp_retrain_link(struct intel_encoder *encoder,
...@@ -93,10 +92,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, ...@@ -93,10 +92,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
void void
intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat); u8 dp_train_pat);
void void
intel_dp_set_signal_levels(struct intel_dp *intel_dp); intel_dp_set_signal_levels(struct intel_dp *intel_dp,
void intel_dp_set_idle_link_train(struct intel_dp *intel_dp); const struct intel_crtc_state *crtc_state);
void intel_dp_set_idle_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
u8 *link_bw, u8 *rate_select); u8 *link_bw, u8 *rate_select);
bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
......
...@@ -49,8 +49,10 @@ static u8 dp_voltage_max(u8 preemph) ...@@ -49,8 +49,10 @@ static u8 dp_voltage_max(u8 preemph)
} }
} }
void intel_dp_get_adjust_train(struct intel_dp *intel_dp, void
const u8 link_status[DP_LINK_STATUS_SIZE]) intel_dp_get_adjust_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
const u8 link_status[DP_LINK_STATUS_SIZE])
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 v = 0; u8 v = 0;
...@@ -59,7 +61,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, ...@@ -59,7 +61,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
u8 voltage_max; u8 voltage_max;
u8 preemph_max; u8 preemph_max;
for (lane = 0; lane < intel_dp->lane_count; lane++) { for (lane = 0; lane < crtc_state->lane_count; lane++) {
v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane)); v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane));
p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane)); p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane));
} }
...@@ -74,7 +76,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, ...@@ -74,7 +76,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
v = min(v, dp_voltage_max(p)); v = min(v, dp_voltage_max(p));
voltage_max = intel_dp->voltage_max(intel_dp); voltage_max = intel_dp->voltage_max(intel_dp, crtc_state);
drm_WARN_ON_ONCE(&i915->drm, drm_WARN_ON_ONCE(&i915->drm,
voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_2 && voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_2 &&
voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_3); voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_3);
...@@ -88,12 +90,14 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, ...@@ -88,12 +90,14 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
static bool static bool
intel_dp_set_link_train(struct intel_dp *intel_dp, intel_dp_set_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat) u8 dp_train_pat)
{ {
u8 buf[sizeof(intel_dp->train_set) + 1]; u8 buf[sizeof(intel_dp->train_set) + 1];
int ret, len; int ret, len;
intel_dp_program_link_training_pattern(intel_dp, dp_train_pat); intel_dp_program_link_training_pattern(intel_dp, crtc_state,
dp_train_pat);
buf[0] = dp_train_pat; buf[0] = dp_train_pat;
if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) == if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
...@@ -102,8 +106,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, ...@@ -102,8 +106,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
len = 1; len = 1;
} else { } else {
/* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */ /* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
memcpy(buf + 1, intel_dp->train_set, intel_dp->lane_count); memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count);
len = intel_dp->lane_count + 1; len = crtc_state->lane_count + 1;
} }
ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
...@@ -114,31 +118,34 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, ...@@ -114,31 +118,34 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
static bool static bool
intel_dp_reset_link_train(struct intel_dp *intel_dp, intel_dp_reset_link_train(struct intel_dp *intel_dp,
u8 dp_train_pat) const struct intel_crtc_state *crtc_state,
u8 dp_train_pat)
{ {
memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
intel_dp_set_signal_levels(intel_dp); intel_dp_set_signal_levels(intel_dp, crtc_state);
return intel_dp_set_link_train(intel_dp, dp_train_pat); return intel_dp_set_link_train(intel_dp, crtc_state, dp_train_pat);
} }
static bool static bool
intel_dp_update_link_train(struct intel_dp *intel_dp) intel_dp_update_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
int ret; int ret;
intel_dp_set_signal_levels(intel_dp); intel_dp_set_signal_levels(intel_dp, crtc_state);
ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
intel_dp->train_set, intel_dp->lane_count); intel_dp->train_set, crtc_state->lane_count);
return ret == intel_dp->lane_count; return ret == crtc_state->lane_count;
} }
static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp) static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
int lane; int lane;
for (lane = 0; lane < intel_dp->lane_count; lane++) for (lane = 0; lane < crtc_state->lane_count; lane++)
if ((intel_dp->train_set[lane] & if ((intel_dp->train_set[lane] &
DP_TRAIN_MAX_SWING_REACHED) == 0) DP_TRAIN_MAX_SWING_REACHED) == 0)
return false; return false;
...@@ -148,7 +155,8 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp) ...@@ -148,7 +155,8 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
/* Enable corresponding port and start training pattern 1 */ /* Enable corresponding port and start training pattern 1 */
static bool static bool
intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 voltage; u8 voltage;
...@@ -158,9 +166,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -158,9 +166,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
u8 link_bw, rate_select; u8 link_bw, rate_select;
if (intel_dp->prepare_link_retrain) if (intel_dp->prepare_link_retrain)
intel_dp->prepare_link_retrain(intel_dp); intel_dp->prepare_link_retrain(intel_dp, crtc_state);
intel_dp_compute_rate(intel_dp, intel_dp->link_rate, intel_dp_compute_rate(intel_dp, crtc_state->port_clock,
&link_bw, &rate_select); &link_bw, &rate_select);
if (link_bw) if (link_bw)
...@@ -172,7 +180,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -172,7 +180,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
/* Write the link configuration data */ /* Write the link configuration data */
link_config[0] = link_bw; link_config[0] = link_bw;
link_config[1] = intel_dp->lane_count; link_config[1] = crtc_state->lane_count;
if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2); drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
...@@ -189,7 +197,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -189,7 +197,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
intel_dp->DP |= DP_PORT_EN; intel_dp->DP |= DP_PORT_EN;
/* clock recovery */ /* clock recovery */
if (!intel_dp_reset_link_train(intel_dp, if (!intel_dp_reset_link_train(intel_dp, crtc_state,
DP_TRAINING_PATTERN_1 | DP_TRAINING_PATTERN_1 |
DP_LINK_SCRAMBLING_DISABLE)) { DP_LINK_SCRAMBLING_DISABLE)) {
drm_err(&i915->drm, "failed to enable link training\n"); drm_err(&i915->drm, "failed to enable link training\n");
...@@ -220,7 +228,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -220,7 +228,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
return false; return false;
} }
if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { if (drm_dp_clock_recovery_ok(link_status, crtc_state->lane_count)) {
drm_dbg_kms(&i915->drm, "clock recovery OK\n"); drm_dbg_kms(&i915->drm, "clock recovery OK\n");
return true; return true;
} }
...@@ -239,8 +247,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -239,8 +247,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
/* Update training set as requested by target */ /* Update training set as requested by target */
intel_dp_get_adjust_train(intel_dp, link_status); intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
if (!intel_dp_update_link_train(intel_dp)) { if (!intel_dp_update_link_train(intel_dp, crtc_state)) {
drm_err(&i915->drm, drm_err(&i915->drm,
"failed to update link training\n"); "failed to update link training\n");
return false; return false;
...@@ -252,7 +260,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -252,7 +260,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
else else
voltage_tries = 1; voltage_tries = 1;
if (intel_dp_link_max_vswing_reached(intel_dp)) if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state))
max_vswing_reached = true; max_vswing_reached = true;
} }
...@@ -266,7 +274,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) ...@@ -266,7 +274,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
* or for 1.4 devices that support it, training Pattern 3 for HBR2 * or for 1.4 devices that support it, training Pattern 3 for HBR2
* or 1.2 devices that support it, Training Pattern 2 otherwise. * or 1.2 devices that support it, Training Pattern 2 otherwise.
*/ */
static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) static u32 intel_dp_training_pattern(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
bool source_tps3, sink_tps3, source_tps4, sink_tps4; bool source_tps3, sink_tps3, source_tps4, sink_tps4;
...@@ -280,7 +289,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) ...@@ -280,7 +289,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd); sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd);
if (source_tps4 && sink_tps4) { if (source_tps4 && sink_tps4) {
return DP_TRAINING_PATTERN_4; return DP_TRAINING_PATTERN_4;
} else if (intel_dp->link_rate == 810000) { } else if (crtc_state->port_clock == 810000) {
if (!source_tps4) if (!source_tps4)
drm_dbg_kms(&dp_to_i915(intel_dp)->drm, drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
"8.1 Gbps link rate without source HBR3/TPS4 support\n"); "8.1 Gbps link rate without source HBR3/TPS4 support\n");
...@@ -297,7 +306,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) ...@@ -297,7 +306,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd); sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd);
if (source_tps3 && sink_tps3) { if (source_tps3 && sink_tps3) {
return DP_TRAINING_PATTERN_3; return DP_TRAINING_PATTERN_3;
} else if (intel_dp->link_rate >= 540000) { } else if (crtc_state->port_clock >= 540000) {
if (!source_tps3) if (!source_tps3)
drm_dbg_kms(&dp_to_i915(intel_dp)->drm, drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
">=5.4/6.48 Gbps link rate without source HBR2/TPS3 support\n"); ">=5.4/6.48 Gbps link rate without source HBR2/TPS3 support\n");
...@@ -310,7 +319,8 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) ...@@ -310,7 +319,8 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
} }
static bool static bool
intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int tries; int tries;
...@@ -318,13 +328,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) ...@@ -318,13 +328,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
u8 link_status[DP_LINK_STATUS_SIZE]; u8 link_status[DP_LINK_STATUS_SIZE];
bool channel_eq = false; bool channel_eq = false;
training_pattern = intel_dp_training_pattern(intel_dp); training_pattern = intel_dp_training_pattern(intel_dp, crtc_state);
/* Scrambling is disabled for TPS2/3 and enabled for TPS4 */ /* Scrambling is disabled for TPS2/3 and enabled for TPS4 */
if (training_pattern != DP_TRAINING_PATTERN_4) if (training_pattern != DP_TRAINING_PATTERN_4)
training_pattern |= DP_LINK_SCRAMBLING_DISABLE; training_pattern |= DP_LINK_SCRAMBLING_DISABLE;
/* channel equalization */ /* channel equalization */
if (!intel_dp_set_link_train(intel_dp, if (!intel_dp_set_link_train(intel_dp, crtc_state,
training_pattern)) { training_pattern)) {
drm_err(&i915->drm, "failed to start channel equalization\n"); drm_err(&i915->drm, "failed to start channel equalization\n");
return false; return false;
...@@ -341,7 +351,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) ...@@ -341,7 +351,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
/* Make sure clock is still ok */ /* Make sure clock is still ok */
if (!drm_dp_clock_recovery_ok(link_status, if (!drm_dp_clock_recovery_ok(link_status,
intel_dp->lane_count)) { crtc_state->lane_count)) {
intel_dp_dump_link_status(link_status); intel_dp_dump_link_status(link_status);
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Clock recovery check failed, cannot " "Clock recovery check failed, cannot "
...@@ -350,7 +360,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) ...@@ -350,7 +360,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
} }
if (drm_dp_channel_eq_ok(link_status, if (drm_dp_channel_eq_ok(link_status,
intel_dp->lane_count)) { crtc_state->lane_count)) {
channel_eq = true; channel_eq = true;
drm_dbg_kms(&i915->drm, "Channel EQ done. DP Training " drm_dbg_kms(&i915->drm, "Channel EQ done. DP Training "
"successful\n"); "successful\n");
...@@ -358,8 +368,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) ...@@ -358,8 +368,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
} }
/* Update training set as requested by target */ /* Update training set as requested by target */
intel_dp_get_adjust_train(intel_dp, link_status); intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
if (!intel_dp_update_link_train(intel_dp)) { if (!intel_dp_update_link_train(intel_dp, crtc_state)) {
drm_err(&i915->drm, drm_err(&i915->drm,
"failed to update link training\n"); "failed to update link training\n");
break; break;
...@@ -373,35 +383,37 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) ...@@ -373,35 +383,37 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
"Channel equalization failed 5 times\n"); "Channel equalization failed 5 times\n");
} }
intel_dp_set_idle_link_train(intel_dp); intel_dp_set_idle_link_train(intel_dp, crtc_state);
return channel_eq; return channel_eq;
} }
void intel_dp_stop_link_train(struct intel_dp *intel_dp) void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
intel_dp->link_trained = true; intel_dp->link_trained = true;
intel_dp_set_link_train(intel_dp, intel_dp_set_link_train(intel_dp, crtc_state,
DP_TRAINING_PATTERN_DISABLE); DP_TRAINING_PATTERN_DISABLE);
} }
void void
intel_dp_start_link_train(struct intel_dp *intel_dp) intel_dp_start_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{ {
struct intel_connector *intel_connector = intel_dp->attached_connector; struct intel_connector *intel_connector = intel_dp->attached_connector;
if (!intel_dp_link_training_clock_recovery(intel_dp)) if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state))
goto failure_handling; goto failure_handling;
if (!intel_dp_link_training_channel_equalization(intel_dp)) if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state))
goto failure_handling; goto failure_handling;
drm_dbg_kms(&dp_to_i915(intel_dp)->drm, drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
"[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d", "[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d",
intel_connector->base.base.id, intel_connector->base.base.id,
intel_connector->base.name, intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count); crtc_state->port_clock, crtc_state->lane_count);
return; return;
failure_handling: failure_handling:
...@@ -409,15 +421,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) ...@@ -409,15 +421,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
"[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d", "[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
intel_connector->base.base.id, intel_connector->base.base.id,
intel_connector->base.name, intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count); crtc_state->port_clock, crtc_state->lane_count);
if (intel_dp->hobl_active) { if (intel_dp->hobl_active) {
drm_dbg_kms(&dp_to_i915(intel_dp)->drm, drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
"Link Training failed with HOBL active, not enabling it from now on"); "Link Training failed with HOBL active, not enabling it from now on");
intel_dp->hobl_failed = true; intel_dp->hobl_failed = true;
} else if (intel_dp_get_link_train_fallback_values(intel_dp, } else if (intel_dp_get_link_train_fallback_values(intel_dp,
intel_dp->link_rate, crtc_state->port_clock,
intel_dp->lane_count)) { crtc_state->lane_count)) {
return; return;
} }
......
...@@ -8,11 +8,15 @@ ...@@ -8,11 +8,15 @@
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
struct intel_crtc_state;
struct intel_dp; struct intel_dp;
void intel_dp_get_adjust_train(struct intel_dp *intel_dp, void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
const u8 link_status[DP_LINK_STATUS_SIZE]); const u8 link_status[DP_LINK_STATUS_SIZE]);
void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_start_link_train(struct intel_dp *intel_dp,
void intel_dp_stop_link_train(struct intel_dp *intel_dp); const struct intel_crtc_state *crtc_state);
void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
#endif /* __INTEL_DP_LINK_TRAINING_H__ */ #endif /* __INTEL_DP_LINK_TRAINING_H__ */
...@@ -644,16 +644,16 @@ bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) ...@@ -644,16 +644,16 @@ bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
return mask; return mask;
} }
void chv_set_phy_signal_level(struct intel_encoder *encoder, void chv_set_phy_signal_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
u32 deemph_reg_value, u32 margin_reg_value, u32 deemph_reg_value, u32 margin_reg_value,
bool uniq_trans_scale) bool uniq_trans_scale)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port); enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = crtc->pipe;
u32 val; u32 val;
int i; int i;
...@@ -666,7 +666,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, ...@@ -666,7 +666,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
if (intel_crtc->config->lane_count > 2) { if (crtc_state->lane_count > 2) {
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
...@@ -679,7 +679,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, ...@@ -679,7 +679,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val); vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
if (intel_crtc->config->lane_count > 2) { if (crtc_state->lane_count > 2) {
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch)); val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
...@@ -687,7 +687,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, ...@@ -687,7 +687,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
} }
/* Program swing deemph */ /* Program swing deemph */
for (i = 0; i < intel_crtc->config->lane_count; i++) { for (i = 0; i < crtc_state->lane_count; i++) {
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i)); val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
val &= ~DPIO_SWING_DEEMPH9P5_MASK; val &= ~DPIO_SWING_DEEMPH9P5_MASK;
val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT; val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
...@@ -695,7 +695,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, ...@@ -695,7 +695,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
} }
/* Program swing margin */ /* Program swing margin */
for (i = 0; i < intel_crtc->config->lane_count; i++) { for (i = 0; i < crtc_state->lane_count; i++) {
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
val &= ~DPIO_SWING_MARGIN000_MASK; val &= ~DPIO_SWING_MARGIN000_MASK;
...@@ -718,7 +718,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, ...@@ -718,7 +718,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
* For now, for this unique transition scale selection, set bit * For now, for this unique transition scale selection, set bit
* 27 for ch0 and ch1. * 27 for ch0 and ch1.
*/ */
for (i = 0; i < intel_crtc->config->lane_count; i++) { for (i = 0; i < crtc_state->lane_count; i++) {
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i)); val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
if (uniq_trans_scale) if (uniq_trans_scale)
val |= DPIO_TX_UNIQ_TRANS_SCALE_EN; val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
...@@ -732,7 +732,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, ...@@ -732,7 +732,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
if (intel_crtc->config->lane_count > 2) { if (crtc_state->lane_count > 2) {
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
...@@ -992,14 +992,15 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder, ...@@ -992,14 +992,15 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
} }
void vlv_set_phy_signal_level(struct intel_encoder *encoder, void vlv_set_phy_signal_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
u32 demph_reg_value, u32 preemph_reg_value, u32 demph_reg_value, u32 preemph_reg_value,
u32 uniqtranscale_reg_value, u32 tx3_demph) u32 uniqtranscale_reg_value, u32 tx3_demph)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel port = vlv_dig_port_to_channel(dig_port); enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = crtc->pipe;
vlv_dpio_get(dev_priv); vlv_dpio_get(dev_priv);
......
...@@ -32,6 +32,7 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, ...@@ -32,6 +32,7 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder,
u8 bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder); u8 bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder);
void chv_set_phy_signal_level(struct intel_encoder *encoder, void chv_set_phy_signal_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
u32 deemph_reg_value, u32 margin_reg_value, u32 deemph_reg_value, u32 margin_reg_value,
bool uniq_trans_scale); bool uniq_trans_scale);
void chv_data_lane_soft_reset(struct intel_encoder *encoder, void chv_data_lane_soft_reset(struct intel_encoder *encoder,
...@@ -46,6 +47,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder, ...@@ -46,6 +47,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state); const struct intel_crtc_state *old_crtc_state);
void vlv_set_phy_signal_level(struct intel_encoder *encoder, void vlv_set_phy_signal_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
u32 demph_reg_value, u32 preemph_reg_value, u32 demph_reg_value, u32 preemph_reg_value,
u32 uniqtranscale_reg_value, u32 tx3_demph); u32 uniqtranscale_reg_value, u32 tx3_demph);
void vlv_phy_pre_pll_enable(struct intel_encoder *encoder, void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
......
...@@ -2775,8 +2775,9 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state, ...@@ -2775,8 +2775,9 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
vlv_phy_pre_encoder_enable(encoder, pipe_config); vlv_phy_pre_encoder_enable(encoder, pipe_config);
/* HDMI 1.0V-2dB */ /* HDMI 1.0V-2dB */
vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a, vlv_set_phy_signal_level(encoder, pipe_config,
0x2b247878); 0x2b245f5f, 0x00002000,
0x5578b83a, 0x2b247878);
dig_port->set_infoframes(encoder, dig_port->set_infoframes(encoder,
pipe_config->has_infoframe, pipe_config->has_infoframe,
...@@ -2853,7 +2854,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state, ...@@ -2853,7 +2854,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
/* FIXME: Program the support xxx V-dB */ /* FIXME: Program the support xxx V-dB */
/* Use 800mV-0dB */ /* Use 800mV-0dB */
chv_set_phy_signal_level(encoder, 128, 102, false); chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false);
dig_port->set_infoframes(encoder, dig_port->set_infoframes(encoder,
pipe_config->has_infoframe, pipe_config->has_infoframe,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment