@@ -4551,6 +4551,13 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC);
}
+static void intel_ddi_sync_state(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ if (intel_crtc_has_dp_encoder(crtc_state))
+ intel_dp_sync_state(encoder, crtc_state);
+}
+
static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
@@ -5175,6 +5182,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->update_pipe = intel_ddi_update_pipe;
encoder->get_hw_state = intel_ddi_get_hw_state;
encoder->get_config = intel_ddi_get_config;
+ encoder->sync_state = intel_ddi_sync_state;
encoder->initial_fastset_check = intel_ddi_initial_fastset_check;
encoder->suspend = intel_dp_encoder_suspend;
encoder->get_power_domains = intel_ddi_get_power_domains;
@@ -18511,6 +18511,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
encoder->base.crtc = &crtc->base;
encoder->get_config(encoder, crtc_state);
+ if (encoder->sync_state)
+ encoder->sync_state(encoder, crtc_state);
} else {
encoder->base.crtc = NULL;
}
@@ -188,6 +188,13 @@ struct intel_encoder {
void (*get_config)(struct intel_encoder *,
struct intel_crtc_state *pipe_config);
+ /*
+ * Optional hook called during init/resume to sync any state
+ * stored in the encoder (eg. DP link parameters) wrt. the HW state.
+ */
+ void (*sync_state)(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state);
+
/*
* Optional hook, returning true if this encoder allows a fastset
* during the initial commit, false otherwise.
@@ -3691,6 +3691,33 @@ 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)
{
@@ -8067,6 +8094,7 @@ 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;
@@ -138,5 +138,7 @@ int intel_dp_init_hdcp(struct intel_digital_port *dig_port,
bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state);
+void intel_dp_sync_state(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state);
#endif /* __INTEL_DP_H__ */