|
@@ -56,6 +56,43 @@
|
|
|
#include "intel_drv.h"
|
|
|
#include "i915_drv.h"
|
|
|
|
|
|
+static inline enum intel_display_power_domain
|
|
|
+psr_aux_domain(struct intel_dp *intel_dp)
|
|
|
+{
|
|
|
+ /* CNL HW requires corresponding AUX IOs to be powered up for PSR.
|
|
|
+ * However, for non-A AUX ports the corresponding non-EDP transcoders
|
|
|
+ * would have already enabled power well 2 and DC_OFF. This means we can
|
|
|
+ * acquire a wider POWER_DOMAIN_AUX_{B,C,D,F} reference instead of a
|
|
|
+ * specific AUX_IO reference without powering up any extra wells.
|
|
|
+ * Note that PSR is enabled only on Port A even though this function
|
|
|
+ * returns the correct domain for other ports too.
|
|
|
+ */
|
|
|
+ return intel_dp->aux_ch == AUX_CH_A ? POWER_DOMAIN_AUX_IO_A :
|
|
|
+ intel_dp->aux_power_domain;
|
|
|
+}
|
|
|
+
|
|
|
+static void psr_aux_io_power_get(struct intel_dp *intel_dp)
|
|
|
+{
|
|
|
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
|
|
+ struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
|
|
|
+
|
|
|
+ if (INTEL_GEN(dev_priv) < 10)
|
|
|
+ return;
|
|
|
+
|
|
|
+ intel_display_power_get(dev_priv, psr_aux_domain(intel_dp));
|
|
|
+}
|
|
|
+
|
|
|
+static void psr_aux_io_power_put(struct intel_dp *intel_dp)
|
|
|
+{
|
|
|
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
|
|
+ struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
|
|
|
+
|
|
|
+ if (INTEL_GEN(dev_priv) < 10)
|
|
|
+ return;
|
|
|
+
|
|
|
+ intel_display_power_put(dev_priv, psr_aux_domain(intel_dp));
|
|
|
+}
|
|
|
+
|
|
|
static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
@@ -459,6 +496,8 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp,
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
|
|
u32 chicken;
|
|
|
|
|
|
+ psr_aux_io_power_get(intel_dp);
|
|
|
+
|
|
|
if (dev_priv->psr.psr2_support) {
|
|
|
chicken = PSR2_VSC_ENABLE_PROG_HEADER;
|
|
|
if (dev_priv->psr.y_cord_support)
|
|
@@ -617,6 +656,8 @@ static void hsw_psr_disable(struct intel_dp *intel_dp,
|
|
|
else
|
|
|
WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
|
|
|
}
|
|
|
+
|
|
|
+ psr_aux_io_power_put(intel_dp);
|
|
|
}
|
|
|
|
|
|
/**
|