aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c682
1 files changed, 458 insertions, 224 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index bf1e9cf1c0f3..cf09aca7607b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -28,7 +28,6 @@
#include <linux/export.h>
#include <linux/i2c.h>
#include <linux/notifier.h>
-#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -161,6 +160,7 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
162000, 270000, 540000, 810000
};
int i, max_rate;
+ int max_lttpr_rate;
if (drm_dp_has_quirk(&intel_dp->desc, 0,
DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS)) {
@@ -174,6 +174,9 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
}
max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
+ max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps);
+ if (max_lttpr_rate)
+ max_rate = min(max_rate, max_lttpr_rate);
for (i = 0; i < ARRAY_SIZE(dp_rates); i++) {
if (dp_rates[i] > max_rate)
@@ -219,6 +222,10 @@ static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
int source_max = dig_port->max_lanes;
int sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
int fia_max = intel_tc_port_fia_max_lane_count(dig_port);
+ int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
+
+ if (lttpr_max)
+ sink_max = min(sink_max, lttpr_max);
return min3(source_max, sink_max, fia_max);
}
@@ -277,13 +284,20 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
if (intel_phy_is_combo(dev_priv, phy) &&
- !IS_ELKHARTLAKE(dev_priv) &&
!intel_dp_is_edp(intel_dp))
return 540000;
return 810000;
}
+static int ehl_max_source_rate(struct intel_dp *intel_dp)
+{
+ if (intel_dp_is_edp(intel_dp))
+ return 540000;
+
+ return 810000;
+}
+
static void
intel_dp_set_source_rates(struct intel_dp *intel_dp)
{
@@ -318,6 +332,8 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
size = ARRAY_SIZE(cnl_rates);
if (IS_GEN(dev_priv, 10))
max_rate = cnl_max_source_rate(intel_dp);
+ else if (IS_JSL_EHL(dev_priv))
+ max_rate = ehl_max_source_rate(intel_dp);
else
max_rate = icl_max_source_rate(intel_dp);
} else if (IS_GEN9_LP(dev_priv)) {
@@ -592,6 +608,54 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
return 0;
}
+static enum intel_output_format
+intel_dp_output_format(struct drm_connector *connector,
+ const struct drm_display_mode *mode)
+{
+ struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
+ const struct drm_display_info *info = &connector->display_info;
+
+ if (!connector->ycbcr_420_allowed ||
+ !drm_mode_is_420_only(info, mode))
+ return INTEL_OUTPUT_FORMAT_RGB;
+
+ if (intel_dp->dfp.ycbcr_444_to_420)
+ return INTEL_OUTPUT_FORMAT_YCBCR444;
+ else
+ return INTEL_OUTPUT_FORMAT_YCBCR420;
+}
+
+int intel_dp_min_bpp(enum intel_output_format output_format)
+{
+ if (output_format == INTEL_OUTPUT_FORMAT_RGB)
+ return 6 * 3;
+ else
+ return 8 * 3;
+}
+
+static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
+{
+ /*
+ * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
+ * format of the number of bytes per pixel will be half the number
+ * of bytes of RGB pixel.
+ */
+ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ bpp /= 2;
+
+ return bpp;
+}
+
+static int
+intel_dp_mode_min_output_bpp(struct drm_connector *connector,
+ const struct drm_display_mode *mode)
+{
+ enum intel_output_format output_format =
+ intel_dp_output_format(connector, mode);
+
+ return intel_dp_output_bpp(output_format, intel_dp_min_bpp(output_format));
+}
+
static bool intel_dp_hdisplay_bad(struct drm_i915_private *dev_priv,
int hdisplay)
{
@@ -671,7 +735,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
max_lanes = intel_dp_max_lane_count(intel_dp);
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
- mode_rate = intel_dp_link_required(target_clock, 18);
+ mode_rate = intel_dp_link_required(target_clock,
+ intel_dp_mode_min_output_bpp(connector, mode));
if (intel_dp_hdisplay_bad(dev_priv, mode->hdisplay))
return MODE_H_ILLEGAL;
@@ -1143,41 +1208,6 @@ _pp_stat_reg(struct intel_dp *intel_dp)
return regs.pp_stat;
}
-/* Reboot notifier handler to shutdown panel power to guarantee T12 timing
- This function only applicable when panel PM state is not to be tracked */
-static int edp_notify_handler(struct notifier_block *this, unsigned long code,
- void *unused)
-{
- struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp),
- edp_notifier);
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- intel_wakeref_t wakeref;
-
- if (!intel_dp_is_edp(intel_dp) || code != SYS_RESTART)
- return 0;
-
- with_pps_lock(intel_dp, wakeref) {
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
- i915_reg_t pp_ctrl_reg, pp_div_reg;
- u32 pp_div;
-
- pp_ctrl_reg = PP_CONTROL(pipe);
- pp_div_reg = PP_DIVISOR(pipe);
- pp_div = intel_de_read(dev_priv, pp_div_reg);
- pp_div &= PP_REFERENCE_DIVIDER_MASK;
-
- /* 0x1F write to PP_DIV_REG sets max cycle delay */
- intel_de_write(dev_priv, pp_div_reg, pp_div | 0x1F);
- intel_de_write(dev_priv, pp_ctrl_reg,
- PANEL_UNLOCK_REGS);
- msleep(intel_dp->panel_power_cycle_delay);
- }
- }
-
- return 0;
-}
-
static bool edp_have_panel_power(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1744,7 +1774,6 @@ static i915_reg_t skl_aux_ctl_reg(struct intel_dp *intel_dp)
case AUX_CH_D:
case AUX_CH_E:
case AUX_CH_F:
- case AUX_CH_G:
return DP_AUX_CH_CTL(aux_ch);
default:
MISSING_CASE(aux_ch);
@@ -1765,7 +1794,52 @@ static i915_reg_t skl_aux_data_reg(struct intel_dp *intel_dp, int index)
case AUX_CH_D:
case AUX_CH_E:
case AUX_CH_F:
- case AUX_CH_G:
+ return DP_AUX_CH_DATA(aux_ch, index);
+ default:
+ MISSING_CASE(aux_ch);
+ return DP_AUX_CH_DATA(AUX_CH_A, index);
+ }
+}
+
+static i915_reg_t tgl_aux_ctl_reg(struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ enum aux_ch aux_ch = dig_port->aux_ch;
+
+ switch (aux_ch) {
+ case AUX_CH_A:
+ case AUX_CH_B:
+ case AUX_CH_C:
+ case AUX_CH_USBC1:
+ case AUX_CH_USBC2:
+ case AUX_CH_USBC3:
+ case AUX_CH_USBC4:
+ case AUX_CH_USBC5:
+ case AUX_CH_USBC6:
+ return DP_AUX_CH_CTL(aux_ch);
+ default:
+ MISSING_CASE(aux_ch);
+ return DP_AUX_CH_CTL(AUX_CH_A);
+ }
+}
+
+static i915_reg_t tgl_aux_data_reg(struct intel_dp *intel_dp, int index)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ enum aux_ch aux_ch = dig_port->aux_ch;
+
+ switch (aux_ch) {
+ case AUX_CH_A:
+ case AUX_CH_B:
+ case AUX_CH_C:
+ case AUX_CH_USBC1:
+ case AUX_CH_USBC2:
+ case AUX_CH_USBC3:
+ case AUX_CH_USBC4:
+ case AUX_CH_USBC5:
+ case AUX_CH_USBC6:
return DP_AUX_CH_DATA(aux_ch, index);
default:
MISSING_CASE(aux_ch);
@@ -1785,8 +1859,12 @@ intel_dp_aux_init(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *encoder = &dig_port->base;
+ enum aux_ch aux_ch = dig_port->aux_ch;
- if (INTEL_GEN(dev_priv) >= 9) {
+ if (INTEL_GEN(dev_priv) >= 12) {
+ intel_dp->aux_ch_ctl_reg = tgl_aux_ctl_reg;
+ intel_dp->aux_ch_data_reg = tgl_aux_data_reg;
+ } else if (INTEL_GEN(dev_priv) >= 9) {
intel_dp->aux_ch_ctl_reg = skl_aux_ctl_reg;
intel_dp->aux_ch_data_reg = skl_aux_data_reg;
} else if (HAS_PCH_SPLIT(dev_priv)) {
@@ -1814,9 +1892,15 @@ intel_dp_aux_init(struct intel_dp *intel_dp)
drm_dp_aux_init(&intel_dp->aux);
/* Failure to allocate our preferred name is not critical */
- intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX %c/port %c",
- aux_ch_name(dig_port->aux_ch),
- port_name(encoder->port));
+ if (INTEL_GEN(dev_priv) >= 12 && aux_ch >= AUX_CH_USBC1)
+ intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX USBC%c/%s",
+ aux_ch - AUX_CH_USBC1 + '1',
+ encoder->base.name);
+ else
+ intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX %c/%s",
+ aux_ch_name(aux_ch),
+ encoder->base.name);
+
intel_dp->aux.transfer = intel_dp_aux_transfer;
}
@@ -2095,19 +2179,6 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
}
}
-static int intel_dp_output_bpp(const struct intel_crtc_state *crtc_state, int bpp)
-{
- /*
- * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
- * format of the number of bytes per pixel will be half the number
- * of bytes of RGB pixel.
- */
- if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
- bpp /= 2;
-
- return bpp;
-}
-
/* Optimize link config in order: max bpp, min clock, min lanes */
static int
intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
@@ -2119,7 +2190,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
int mode_rate, link_clock, link_avail;
for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {
- int output_bpp = intel_dp_output_bpp(pipe_config, bpp);
+ int output_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);
mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
output_bpp);
@@ -2330,14 +2401,6 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
return 0;
}
-int intel_dp_min_bpp(const struct intel_crtc_state *crtc_state)
-{
- if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB)
- return 6 * 3;
- else
- return 8 * 3;
-}
-
static int
intel_dp_compute_link_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -2363,7 +2426,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
limits.min_lane_count = 1;
limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
- limits.min_bpp = intel_dp_min_bpp(pipe_config);
+ limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format);
limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config);
if (intel_dp_is_edp(intel_dp)) {
@@ -2429,32 +2492,6 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
return 0;
}
-static int
-intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state,
- const struct drm_connector_state *conn_state)
-{
- struct drm_connector *connector = conn_state->connector;
- const struct drm_display_info *info = &connector->display_info;
- const struct drm_display_mode *adjusted_mode =
- &crtc_state->hw.adjusted_mode;
-
- if (!connector->ycbcr_420_allowed)
- return 0;
-
- if (!drm_mode_is_420_only(info, adjusted_mode))
- return 0;
-
- if (intel_dp->dfp.ycbcr_444_to_420) {
- crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
- return 0;
- }
-
- crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
-
- return intel_pch_panel_fitting(crtc_state, conn_state);
-}
-
bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
@@ -2693,7 +2730,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder);
enum port port = encoder->port;
struct intel_connector *intel_connector = intel_dp->attached_connector;
struct intel_digital_connector_state *intel_conn_state =
@@ -2705,15 +2741,14 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
pipe_config->has_pch_encoder = true;
- pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
+ pipe_config->output_format = intel_dp_output_format(&intel_connector->base,
+ adjusted_mode);
- if (lspcon->active)
- lspcon_ycbcr420_config(&intel_connector->base, pipe_config);
- else
- ret = intel_dp_ycbcr420_config(intel_dp, pipe_config,
- conn_state);
- if (ret)
- return ret;
+ if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
+ ret = intel_pch_panel_fitting(pipe_config, conn_state);
+ if (ret)
+ return ret;
+ }
if (!intel_dp_port_has_audio(dev_priv, port))
pipe_config->has_audio = false;
@@ -2757,7 +2792,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (pipe_config->dsc.compression_enable)
output_bpp = pipe_config->dsc.compressed_bpp;
else
- output_bpp = intel_dp_output_bpp(pipe_config, pipe_config->pipe_bpp);
+ output_bpp = intel_dp_output_bpp(pipe_config->output_format,
+ pipe_config->pipe_bpp);
intel_link_compute_m_n(output_bpp,
pipe_config->lane_count,
@@ -2779,13 +2815,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
}
void intel_dp_set_link_params(struct intel_dp *intel_dp,
- int link_rate, u8 lane_count,
- bool link_mst)
+ int link_rate, int lane_count)
{
intel_dp->link_trained = false;
intel_dp->link_rate = link_rate;
intel_dp->lane_count = lane_count;
- intel_dp->link_mst = link_mst;
}
static void intel_dp_prepare(struct intel_encoder *encoder,
@@ -2797,10 +2831,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
- intel_dp_set_link_params(intel_dp, pipe_config->port_clock,
- pipe_config->lane_count,
- intel_crtc_has_type(pipe_config,
- INTEL_OUTPUT_DP_MST));
+ intel_dp_set_link_params(intel_dp,
+ pipe_config->port_clock,
+ pipe_config->lane_count);
/*
* There are four kinds of DP registers:
@@ -3492,32 +3525,33 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
enable ? "enable" : "disable");
}
-/* If the sink supports it, try to set the power state appropriately */
-void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
+/* If the device supports it, try to set the power state appropriately */
+void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
int ret, i;
/* Should have a valid DPCD by this point */
if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
return;
- if (mode != DRM_MODE_DPMS_ON) {
+ if (mode != DP_SET_POWER_D0) {
if (downstream_hpd_needs_d0(intel_dp))
return;
- ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
- DP_SET_POWER_D3);
+ ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode);
} else {
struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
+ lspcon_resume(dp_to_dig_port(intel_dp));
+
/*
* When turning on, we need to retry for 1ms to give the sink
* time to wake up.
*/
for (i = 0; i < 3; i++) {
- ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
- DP_SET_POWER_D0);
+ ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode);
if (ret == 1)
break;
msleep(1);
@@ -3528,8 +3562,9 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
}
if (ret != 1)
- drm_dbg_kms(&i915->drm, "failed to %s sink power state\n",
- mode == DRM_MODE_DPMS_ON ? "enable" : "disable");
+ drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Set power to %s failed\n",
+ encoder->base.base.id, encoder->base.name,
+ mode == DP_SET_POWER_D0 ? "D0" : "D3");
}
static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
@@ -3686,6 +3721,66 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
}
}
+static bool
+intel_dp_get_dpcd(struct intel_dp *intel_dp);
+
+/**
+ * intel_dp_sync_state - sync the encoder state during init/resume
+ * @encoder: intel encoder to sync
+ * @crtc_state: state for the CRTC connected to the encoder
+ *
+ * Sync any state stored in the encoder wrt. HW state during driver init
+ * and system resume.
+ */
+void intel_dp_sync_state(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ /*
+ * Don't clobber DPCD if it's been already read out during output
+ * setup (eDP) or detect.
+ */
+ if (intel_dp->dpcd[DP_DPCD_REV] == 0)
+ intel_dp_get_dpcd(intel_dp);
+
+ intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp);
+ intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
+}
+
+bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ /*
+ * If BIOS has set an unsupported or non-standard link rate for some
+ * reason force an encoder recompute and full modeset.
+ */
+ if (intel_dp_rate_index(intel_dp->source_rates, intel_dp->num_source_rates,
+ crtc_state->port_clock) < 0) {
+ drm_dbg_kms(&i915->drm, "Forcing full modeset due to unsupported link rate\n");
+ crtc_state->uapi.connectors_changed = true;
+ return false;
+ }
+
+ /*
+ * FIXME hack to force full modeset when DSC is being used.
+ *
+ * As long as we do not have full state readout and config comparison
+ * of crtc_state->dsc, we have no way to ensure reliable fastset.
+ * Remove once we have readout for DSC.
+ */
+ if (crtc_state->dsc.compression_enable) {
+ drm_dbg_kms(&i915->drm, "Forcing full modeset due to DSC being enabled\n");
+ crtc_state->uapi.mode_changed = true;
+ return false;
+ }
+
+ return true;
+}
+
static void intel_disable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
@@ -3703,7 +3798,7 @@ static void intel_disable_dp(struct intel_atomic_state *state,
* ensure that we have vdd while we switch off the panel. */
intel_edp_panel_vdd_on(intel_dp);
intel_edp_backlight_off(old_conn_state);
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+ intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
intel_edp_panel_off(intel_dp);
}
@@ -3771,6 +3866,7 @@ static void chv_post_disable_dp(struct intel_atomic_state *state,
static void
cpt_set_link_train(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
u8 dp_train_pat)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -3778,7 +3874,7 @@ cpt_set_link_train(struct intel_dp *intel_dp,
*DP &= ~DP_LINK_TRAIN_MASK_CPT;
- switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+ switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
case DP_TRAINING_PATTERN_DISABLE:
*DP |= DP_LINK_TRAIN_OFF_CPT;
break;
@@ -3801,6 +3897,7 @@ cpt_set_link_train(struct intel_dp *intel_dp,
static void
g4x_set_link_train(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
u8 dp_train_pat)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -3808,7 +3905,7 @@ g4x_set_link_train(struct intel_dp *intel_dp,
*DP &= ~DP_LINK_TRAIN_MASK;
- switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+ switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
case DP_TRAINING_PATTERN_DISABLE:
*DP |= DP_LINK_TRAIN_OFF;
break;
@@ -3830,13 +3927,14 @@ g4x_set_link_train(struct intel_dp *intel_dp,
}
static void intel_dp_enable_port(struct intel_dp *intel_dp,
- const struct intel_crtc_state *old_crtc_state)
+ const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
/* 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
@@ -3845,7 +3943,7 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
* fail when the power sequencer is freshly used for this port.
*/
intel_dp->DP |= DP_PORT_EN;
- if (old_crtc_state->has_audio)
+ if (crtc_state->has_audio)
intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
@@ -3925,10 +4023,10 @@ static void intel_enable_dp(struct intel_atomic_state *state,
lane_mask);
}
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+ intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp);
- intel_dp_start_link_train(intel_dp);
- intel_dp_stop_link_train(intel_dp);
+ intel_dp_start_link_train(intel_dp, pipe_config);
+ intel_dp_stop_link_train(intel_dp, pipe_config);
if (pipe_config->has_audio) {
drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n",
@@ -4126,38 +4224,30 @@ static void chv_dp_post_pll_disable(struct intel_atomic_state *state,
chv_phy_post_pll_disable(encoder, old_crtc_state);
}
-/*
- * Fetch AUX CH registers 0x202 - 0x207 which contain
- * link status information
- */
-bool
-intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE])
-{
- return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status,
- 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;
}
-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;
}
-static u8 intel_dp_pre_empemph_max_2(struct intel_dp *intel_dp)
+static u8 intel_dp_preemph_max_2(struct intel_dp *intel_dp)
{
return DP_TRAIN_PRE_EMPH_LEVEL_2;
}
-static u8 intel_dp_pre_empemph_max_3(struct intel_dp *intel_dp)
+static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp)
{
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;
unsigned long demph_reg_value, preemph_reg_value,
@@ -4237,11 +4327,13 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp)
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);
}
-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;
u32 deemph_reg_value, margin_reg_value;
@@ -4318,8 +4410,9 @@ static void chv_set_signal_levels(struct intel_dp *intel_dp)
return;
}
- chv_set_phy_signal_level(encoder, deemph_reg_value,
- margin_reg_value, uniq_trans_scale);
+ chv_set_phy_signal_level(encoder, crtc_state,
+ deemph_reg_value, margin_reg_value,
+ uniq_trans_scale);
}
static u32 g4x_signal_levels(u8 train_set)
@@ -4360,7 +4453,8 @@ static u32 g4x_signal_levels(u8 train_set)
}
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);
u8 train_set = intel_dp->train_set[0];
@@ -4407,7 +4501,8 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set)
}
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);
u8 train_set = intel_dp->train_set[0];
@@ -4458,7 +4553,8 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set)
}
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);
u8 train_set = intel_dp->train_set[0];
@@ -4476,7 +4572,8 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
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);
u8 train_set = intel_dp->train_set[0];
@@ -4490,28 +4587,23 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp)
train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
" (max)" : "");
- intel_dp->set_signal_levels(intel_dp);
+ intel_dp->set_signal_levels(intel_dp, crtc_state);
}
void
intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
u8 dp_train_pat)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
- if (dp_train_pat & train_pat_mask)
+ if ((intel_dp_training_pattern_symbol(dp_train_pat)) !=
+ DP_TRAINING_PATTERN_DISABLE)
drm_dbg_kms(&dev_priv->drm,
"Using DP training pattern TPS%d\n",
- dp_train_pat & train_pat_mask);
+ intel_dp_training_pattern_symbol(dp_train_pat));
- intel_dp->set_link_train(intel_dp, dp_train_pat);
-}
-
-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
-{
- if (intel_dp->set_idle_link_train)
- intel_dp->set_idle_link_train(intel_dp);
+ intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat);
}
static void
@@ -4732,6 +4824,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
{
int ret;
+ intel_dp_lttpr_init(intel_dp);
+
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd))
return false;
@@ -5404,33 +5498,14 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
return test_result;
}
-static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp)
-{
- struct drm_dp_phy_test_params *data =
- &intel_dp->compliance.test_data.phytest;
-
- if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) {
- DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n");
- return DP_TEST_NAK;
- }
-
- /*
- * link_mst is set to false to avoid executing mst related code
- * during compliance testing.
- */
- intel_dp->link_mst = false;
-
- return DP_TEST_ACK;
-}
-
-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 =
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 =
&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;
u32 pattern_val;
@@ -5490,7 +5565,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
}
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 drm_device *dev = dig_port->base.base.dev;
@@ -5516,7 +5592,8 @@ intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
}
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 drm_device *dev = dig_port->base.base.dev;
@@ -5542,27 +5619,30 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
trans_ddi_func_ctl_value);
}
-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 =
&intel_dp->compliance.test_data.phytest;
u8 link_status[DP_LINK_STATUS_SIZE];
- if (!intel_dp_get_link_status(intel_dp, link_status)) {
+ if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
+ link_status) < 0) {
DRM_DEBUG_KMS("failed to get link status\n");
return;
}
/* retrieve vswing & pre-emphasis setting */
- intel_dp_get_adjust_train(intel_dp, link_status);
+ intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
+ 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,
link_status[DP_DPCD_REV]);
@@ -5570,15 +5650,18 @@ void intel_dp_process_phy_request(struct intel_dp *intel_dp)
static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
{
- u8 test_result;
+ struct drm_dp_phy_test_params *data =
+ &intel_dp->compliance.test_data.phytest;
- test_result = intel_dp_prepare_phytest(intel_dp);
- if (test_result != DP_TEST_ACK)
- DRM_ERROR("Phy test preparation failed\n");
+ if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) {
+ DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n");
+ return DP_TEST_NAK;
+ }
- intel_dp_process_phy_request(intel_dp);
+ /* Set test active flag here so userspace doesn't interrupt things */
+ intel_dp->compliance.test_active = true;
- return test_result;
+ return DP_TEST_ACK;
}
static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
@@ -5709,12 +5792,17 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
if (intel_psr_enabled(intel_dp))
return false;
- if (!intel_dp_get_link_status(intel_dp, link_status))
+ if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
+ link_status) < 0)
return false;
/*
* Validate the cached values of intel_dp->link_rate and
* 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,
intel_dp->lane_count))
@@ -5848,8 +5936,20 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), false);
}
- intel_dp_start_link_train(intel_dp);
- intel_dp_stop_link_train(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);
+
+ /* 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) {
const struct intel_crtc_state *crtc_state =
@@ -5867,6 +5967,118 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
return 0;
}
+static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
+ struct drm_modeset_acquire_ctx *ctx,
+ u32 *crtc_mask)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct drm_connector_list_iter conn_iter;
+ struct intel_connector *connector;
+ int ret = 0;
+
+ *crtc_mask = 0;
+
+ drm_connector_list_iter_begin(&i915->drm, &conn_iter);
+ for_each_intel_connector_iter(connector, &conn_iter) {
+ struct drm_connector_state *conn_state =
+ connector->base.state;
+ struct intel_crtc_state *crtc_state;
+ struct intel_crtc *crtc;
+
+ if (!intel_dp_has_connector(intel_dp, conn_state))
+ continue;
+
+ crtc = to_intel_crtc(conn_state->crtc);
+ if (!crtc)
+ continue;
+
+ ret = drm_modeset_lock(&crtc->base.mutex, ctx);
+ if (ret)
+ break;
+
+ crtc_state = to_intel_crtc_state(crtc->base.state);
+
+ drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state));
+
+ if (!crtc_state->hw.active)
+ continue;
+
+ if (conn_state->commit &&
+ !try_wait_for_completion(&conn_state->commit->hw_done))
+ continue;
+
+ *crtc_mask |= drm_crtc_mask(&crtc->base);
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return ret;
+}
+
+static int intel_dp_do_phy_test(struct intel_encoder *encoder,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_crtc *crtc;
+ u32 crtc_mask;
+ int ret;
+
+ ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
+ ctx);
+ if (ret)
+ return ret;
+
+ ret = intel_dp_prep_phy_test(intel_dp, ctx, &crtc_mask);
+ if (ret)
+ return ret;
+
+ if (crtc_mask == 0)
+ return 0;
+
+ drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n",
+ encoder->base.base.id, encoder->base.name);
+
+ 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;
+}
+
+static void intel_dp_phy_test(struct intel_encoder *encoder)
+{
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ for (;;) {
+ ret = intel_dp_do_phy_test(encoder, &ctx);
+
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ continue;
+ }
+
+ break;
+ }
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+ drm_WARN(encoder->base.dev, ret,
+ "Acquiring modeset locks failed with %i\n", ret);
+}
+
/*
* If display is now connected check links status,
* there has been known issues of link loss triggering
@@ -5883,10 +6095,18 @@ static enum intel_hotplug_state
intel_dp_hotplug(struct intel_encoder *encoder,
struct intel_connector *connector)
{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_modeset_acquire_ctx ctx;
enum intel_hotplug_state state;
int ret;
+ if (intel_dp->compliance.test_active &&
+ intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
+ intel_dp_phy_test(encoder);
+ /* just do the PHY test and nothing else */
+ return INTEL_HOTPLUG_UNCHANGED;
+ }
+
state = intel_encoder_hotplug(encoder, connector);
drm_modeset_acquire_init(&ctx, 0);
@@ -5991,11 +6211,23 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
intel_psr_short_pulse(intel_dp);
- if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
+ switch (intel_dp->compliance.test_type) {
+ case DP_TEST_LINK_TRAINING:
drm_dbg_kms(&dev_priv->drm,
"Link Training Compliance Test requested\n");
/* Send a Hotplug Uevent to userspace to start modeset */
drm_kms_helper_hotplug_event(&dev_priv->drm);
+ break;
+ case DP_TEST_LINK_PHY_TEST_PATTERN:
+ drm_dbg_kms(&dev_priv->drm,
+ "PHY test pattern Compliance Test requested\n");
+ /*
+ * Schedule long hpd to do the test
+ *
+ * FIXME get rid of the ad-hoc phy test modeset code
+ * and properly incorporate it into the normal modeset.
+ */
+ return false;
}
return true;
@@ -6006,15 +6238,14 @@ static enum drm_connector_status
intel_dp_detect_dpcd(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
u8 *dpcd = intel_dp->dpcd;
u8 type;
if (drm_WARN_ON(&i915->drm, intel_dp_is_edp(intel_dp)))
return connector_status_connected;
- if (lspcon->active)
- lspcon_resume(lspcon);
+ lspcon_resume(dig_port);
if (!intel_dp_get_dpcd(intel_dp))
return connector_status_disconnected;
@@ -6220,7 +6451,9 @@ intel_dp_update_420(struct intel_dp *intel_dp)
ycbcr_420_passthrough =
drm_dp_downstream_420_passthrough(intel_dp->dpcd,
intel_dp->downstream_ports);
+ /* on-board LSPCON always assumed to support 4:4:4->4:2:0 conversion */
ycbcr_444_to_420 =
+ dp_to_dig_port(intel_dp)->lspcon.active ||
drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd,
intel_dp->downstream_ports);
@@ -6523,11 +6756,6 @@ void intel_dp_encoder_flush_work(struct drm_encoder *encoder)
*/
with_pps_lock(intel_dp, wakeref)
edp_panel_vdd_off_sync(intel_dp);
-
- if (intel_dp->edp_notifier.notifier_call) {
- unregister_reboot_notifier(&intel_dp->edp_notifier);
- intel_dp->edp_notifier.notifier_call = NULL;
- }
}
intel_dp_aux_fini(intel_dp);
@@ -6558,6 +6786,18 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
edp_panel_vdd_off_sync(intel_dp);
}
+void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
+ intel_wakeref_t wakeref;
+
+ if (!intel_dp_is_edp(intel_dp))
+ return;
+
+ with_pps_lock(intel_dp, wakeref)
+ wait_panel_power_cycle(intel_dp);
+}
+
static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -6598,15 +6838,11 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
- struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
intel_wakeref_t wakeref;
if (!HAS_DDI(dev_priv))
intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg);
- if (lspcon->active)
- lspcon_resume(lspcon);
-
intel_dp->reset_link_params = true;
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
@@ -7671,9 +7907,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
mutex_unlock(&dev->mode_config.mutex);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- intel_dp->edp_notifier.notifier_call = edp_notify_handler;
- register_reboot_notifier(&intel_dp->edp_notifier);
-
/*
* Figure out the current pipe for the initial backlight setup.
* If the current pipe isn't valid, try the PPS pipe, and if that
@@ -7892,8 +8125,11 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
intel_encoder->compute_config = intel_dp_compute_config;
intel_encoder->get_hw_state = intel_dp_get_hw_state;
intel_encoder->get_config = intel_dp_get_config;
+ intel_encoder->sync_state = intel_dp_sync_state;
+ intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check;
intel_encoder->update_pipe = intel_panel_update_backlight;
intel_encoder->suspend = intel_dp_encoder_suspend;
+ intel_encoder->shutdown = intel_dp_encoder_shutdown;
if (IS_CHERRYVIEW(dev_priv)) {
intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
intel_encoder->pre_enable = chv_pre_enable_dp;
@@ -7933,17 +8169,15 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
(HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
- dig_port->dp.preemph_max = intel_dp_pre_empemph_max_3;
+ dig_port->dp.preemph_max = intel_dp_preemph_max_3;
dig_port->dp.voltage_max = intel_dp_voltage_max_3;
} else {
- dig_port->dp.preemph_max = intel_dp_pre_empemph_max_2;
+ dig_port->dp.preemph_max = intel_dp_preemph_max_2;
dig_port->dp.voltage_max = intel_dp_voltage_max_2;
}
dig_port->dp.output_reg = output_reg;
dig_port->max_lanes = 4;
- dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
- dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
intel_encoder->type = INTEL_OUTPUT_DP;
intel_encoder->power_domain = intel_port_to_power_domain(port);