|
@@ -4677,9 +4677,52 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
|
|
|
pps_unlock(intel_dp);
|
|
|
}
|
|
|
|
|
|
+static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
|
|
|
+{
|
|
|
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
|
|
+ struct drm_device *dev = intel_dig_port->base.base.dev;
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ enum intel_display_power_domain power_domain;
|
|
|
+
|
|
|
+ lockdep_assert_held(&dev_priv->pps_mutex);
|
|
|
+
|
|
|
+ if (!edp_have_panel_vdd(intel_dp))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The VDD bit needs a power domain reference, so if the bit is
|
|
|
+ * already enabled when we boot or resume, grab this reference and
|
|
|
+ * schedule a vdd off, so we don't hold on to the reference
|
|
|
+ * indefinitely.
|
|
|
+ */
|
|
|
+ DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
|
|
|
+ power_domain = intel_display_port_power_domain(&intel_dig_port->base);
|
|
|
+ intel_display_power_get(dev_priv, power_domain);
|
|
|
+
|
|
|
+ edp_panel_vdd_schedule_off(intel_dp);
|
|
|
+}
|
|
|
+
|
|
|
static void intel_dp_encoder_reset(struct drm_encoder *encoder)
|
|
|
{
|
|
|
- intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
|
|
|
+ struct intel_dp *intel_dp;
|
|
|
+
|
|
|
+ if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
|
|
|
+ return;
|
|
|
+
|
|
|
+ intel_dp = enc_to_intel_dp(encoder);
|
|
|
+
|
|
|
+ pps_lock(intel_dp);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Read out the current power sequencer assignment,
|
|
|
+ * in case the BIOS did something with it.
|
|
|
+ */
|
|
|
+ if (IS_VALLEYVIEW(encoder->dev))
|
|
|
+ vlv_initial_power_sequencer_setup(intel_dp);
|
|
|
+
|
|
|
+ intel_edp_panel_vdd_sanitize(intel_dp);
|
|
|
+
|
|
|
+ pps_unlock(intel_dp);
|
|
|
}
|
|
|
|
|
|
static const struct drm_connector_funcs intel_dp_connector_funcs = {
|
|
@@ -5150,37 +5193,6 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
|
|
|
return downclock_mode;
|
|
|
}
|
|
|
|
|
|
-void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
|
|
|
-{
|
|
|
- struct drm_device *dev = intel_encoder->base.dev;
|
|
|
- struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
- struct intel_dp *intel_dp;
|
|
|
- enum intel_display_power_domain power_domain;
|
|
|
-
|
|
|
- if (intel_encoder->type != INTEL_OUTPUT_EDP)
|
|
|
- return;
|
|
|
-
|
|
|
- intel_dp = enc_to_intel_dp(&intel_encoder->base);
|
|
|
-
|
|
|
- pps_lock(intel_dp);
|
|
|
-
|
|
|
- if (!edp_have_panel_vdd(intel_dp))
|
|
|
- goto out;
|
|
|
- /*
|
|
|
- * The VDD bit needs a power domain reference, so if the bit is
|
|
|
- * already enabled when we boot or resume, grab this reference and
|
|
|
- * schedule a vdd off, so we don't hold on to the reference
|
|
|
- * indefinitely.
|
|
|
- */
|
|
|
- DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
|
|
|
- power_domain = intel_display_port_power_domain(intel_encoder);
|
|
|
- intel_display_power_get(dev_priv, power_domain);
|
|
|
-
|
|
|
- edp_panel_vdd_schedule_off(intel_dp);
|
|
|
- out:
|
|
|
- pps_unlock(intel_dp);
|
|
|
-}
|
|
|
-
|
|
|
static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|
|
struct intel_connector *intel_connector)
|
|
|
{
|
|
@@ -5200,7 +5212,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|
|
if (!is_edp(intel_dp))
|
|
|
return true;
|
|
|
|
|
|
- intel_edp_panel_vdd_sanitize(intel_encoder);
|
|
|
+ pps_lock(intel_dp);
|
|
|
+ intel_edp_panel_vdd_sanitize(intel_dp);
|
|
|
+ pps_unlock(intel_dp);
|
|
|
|
|
|
/* Cache DPCD and EDID for edp. */
|
|
|
has_dpcd = intel_dp_get_dpcd(intel_dp);
|