diff options
author | Dave Airlie <airlied@redhat.com> | 2021-10-22 05:49:21 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2021-10-22 05:49:42 +1000 |
commit | 94ff371eb8497d02b8cb9d0c2c7370193c98e9f7 (patch) | |
tree | ff115b1a3b67777d8a2f63c7c87f969cc9550995 /drivers/gpu/drm/i915/display/intel_ddi.c | |
parent | 1176d15f0f6e556d54ced510ac4a91694960332b (diff) | |
parent | c974cf01b248c6f4220bfadd57cce74058453aea (diff) | |
download | linux-94ff371eb8497d02b8cb9d0c2c7370193c98e9f7.tar.gz linux-94ff371eb8497d02b8cb9d0c2c7370193c98e9f7.tar.bz2 linux-94ff371eb8497d02b8cb9d0c2c7370193c98e9f7.zip |
Merge tag 'drm-intel-next-2021-10-15' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
UAPI Changes:
- No Functional change, but a clarification around I915_TILING values (Matt).
Driver Changes:
- Changes around async flip VT-d w/a (Ville)
- Delete bogus NULL check in intel_ddi_encoder_destroy (Dan)
- DP link training improvements and DP per-lane driver settings (Ville)
- Free the returned object of acpi_evaluate_dsm (Zenghui)
- Fixes and improvements around DP's UHBR and MST (Jani)
- refactor plane config + pin out (Dave)
- remove unused include in intel_dsi_vbt.c (Lucas)
- some code clean up (Lucas, Jani)
- gracefully disable dual eDP (Jani)
- Remove memory frequency calculation (Jose)
- Fix oops on platforms w/o hpd support (Ville)
- Clean up PXP Kconfig info (Rodrigo)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/YWnMORrixyw90O3/@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_ddi.c | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 0d4cf7fa8720..1dcfe31e6c6f 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1023,6 +1023,18 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp) return DP_TRAIN_PRE_EMPH_LEVEL_3; } +static u32 icl_combo_phy_loadgen_select(const struct intel_crtc_state *crtc_state, + int lane) +{ + if (crtc_state->port_clock > 600000) + return 0; + + if (crtc_state->lane_count == 4) + return lane >= 1 ? LOADGEN_SELECT : 0; + else + return lane == 1 || lane == 2 ? LOADGEN_SELECT : 0; +} + static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { @@ -1047,7 +1059,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, } /* Set PORT_TX_DW5 */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); + val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | TAP2_DISABLE | TAP3_DISABLE); val |= SCALING_MODE_SEL(0x2); @@ -1056,7 +1068,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); /* Program PORT_TX_DW2 */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN0(phy)); + val = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN(0, phy)); val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK | RCOMP_SCALAR_MASK); val |= SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel); @@ -1067,7 +1079,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, /* Program PORT_TX_DW4 */ /* We cannot write to GRP. It would overwrite individual loadgen. */ - for (ln = 0; ln <= 3; ln++) { + for (ln = 0; ln < 4; ln++) { val = intel_de_read(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy)); val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | CURSOR_COEFF_MASK); @@ -1078,7 +1090,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, } /* Program PORT_TX_DW7 */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW7_LN0(phy)); + val = intel_de_read(dev_priv, ICL_PORT_TX_DW7_LN(0, phy)); val &= ~N_SCALAR_MASK; val |= N_SCALAR(trans->entries[level].icl.dw7_n_scalar); intel_de_write(dev_priv, ICL_PORT_TX_DW7_GRP(phy), val); @@ -1089,18 +1101,15 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - int width, rate, ln; u32 val; - - width = crtc_state->lane_count; - rate = crtc_state->port_clock; + int ln; /* * 1. If port type is eDP or DP, * set PORT_PCS_DW1 cmnkeeper_enable to 1b, * 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_LN(0, phy)); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) val &= ~COMMON_KEEPER_EN; else @@ -1109,19 +1118,15 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, /* 2. Program loadgen select */ /* - * Program PORT_TX_DW4_LN depending on Bit rate and used lanes + * Program PORT_TX_DW4 depending on Bit rate and used lanes * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1) * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0) * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0) */ - for (ln = 0; ln <= 3; ln++) { + for (ln = 0; ln < 4; ln++) { val = intel_de_read(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy)); val &= ~LOADGEN_SELECT; - - if ((rate <= 600000 && width == 4 && ln >= 1) || - (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) { - val |= LOADGEN_SELECT; - } + val |= icl_combo_phy_loadgen_select(crtc_state, ln); intel_de_write(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), val); } @@ -1131,7 +1136,7 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, intel_de_write(dev_priv, ICL_PORT_CL_DW5(phy), val); /* 4. Clear training enable to change swing values */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); + val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~TX_TRAINING_EN; intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); @@ -1139,7 +1144,7 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, icl_ddi_combo_vswing_program(encoder, crtc_state); /* 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_LN(0, phy)); val |= TX_TRAINING_EN; intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); } @@ -1285,9 +1290,9 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | DKL_TX_VSWING_CONTROL_MASK); - dpcnt_val = DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.dkl_vswing_control); - dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.dkl_de_emphasis_control); - dpcnt_val |= DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.dkl_preshoot_control); + dpcnt_val = DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing); + dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis); + dpcnt_val |= DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot); for (ln = 0; ln < 2; ln++) { intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), @@ -1309,14 +1314,6 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, val = intel_de_read(dev_priv, DKL_TX_DPCNTL2(tc_port)); val &= ~DKL_TX_DP20BITMODE; intel_de_write(dev_priv, DKL_TX_DPCNTL2(tc_port), val); - - if ((intel_crtc_has_dp_encoder(crtc_state) && - crtc_state->port_clock == 162000) || - (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && - crtc_state->port_clock == 594000)) - val |= DKL_TX_LOADGEN_SHARING_PMD_DISABLE; - else - val &= ~DKL_TX_LOADGEN_SHARING_PMD_DISABLE; } } @@ -1338,13 +1335,20 @@ static int translate_signal_level(struct intel_dp *intel_dp, return 0; } -static int intel_ddi_dp_level(struct intel_dp *intel_dp, int lane) +static int intel_ddi_dp_level(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + int lane) { u8 train_set = intel_dp->train_set[lane]; - u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | - DP_TRAIN_PRE_EMPHASIS_MASK); - return translate_signal_level(intel_dp, signal_levels); + if (intel_dp_is_uhbr(crtc_state)) { + return train_set & DP_TX_FFE_PRESET_VALUE_MASK; + } else { + u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | + DP_TRAIN_PRE_EMPHASIS_MASK); + + return translate_signal_level(intel_dp, signal_levels); + } } int intel_ddi_level(struct intel_encoder *encoder, @@ -1362,7 +1366,8 @@ int intel_ddi_level(struct intel_encoder *encoder, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) level = intel_ddi_hdmi_level(encoder, trans); else - level = intel_ddi_dp_level(enc_to_intel_dp(encoder), lane); + level = intel_ddi_dp_level(enc_to_intel_dp(encoder), crtc_state, + lane); if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) level = n_entries - 1; @@ -3937,8 +3942,7 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) intel_display_power_flush_work(i915); drm_encoder_cleanup(encoder); - if (dig_port) - kfree(dig_port->hdcp_port_data.streams); + kfree(dig_port->hdcp_port_data.streams); kfree(dig_port); } |