From: Satheeshakrishna M <[email protected]>

This patch enables power well 2 required for any aux transaction.

v2: Implemented Imre's comments
        - In EDID/DPCD related routines, request AUX power well in SKL

v3: Implemented Imre's comments
        - Call AUX power well domain unconditionally for all platforms

v4: Remove the check on the output type for the AUX power domain

v5: Rebase on top of drm-intel-nightly (Damien)

v6: Rebase on top of -nightly (minor conflict in intel_drv.h) (Damien)

v7: Remove platform check while getting power well for port (Imre)

v8: Fix aux power handling around Vdd on/off (Damien)

v9: Acquire aux power domain on enabling vdd in
    intel_edp_panel_vdd_sanitize() (Satheesh)

v10: Rebase on top of Ville's patch to return early in this function intead of
     having a big indented block. (Damien)

v12: Rebase on top of Chris EDID caching work (Damien)

Signed-off-by: Satheeshakrishna M <[email protected]> (v4, v9)
Signed-off-by: Damien Lespiau <[email protected]>
---
 drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++++
 drivers/gpu/drm/i915/intel_dp.c      | 62 ++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_drv.h     |  2 ++
 3 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0a4dd00..abd4201 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4503,6 +4503,27 @@ intel_display_port_power_domain(struct intel_encoder 
*intel_encoder)
        }
 }
 
+enum intel_display_power_domain
+intel_display_aux_power_domain(struct intel_encoder *intel_encoder)
+{
+       struct intel_digital_port *intel_dig_port;
+
+       intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+       switch (intel_dig_port->port) {
+       case PORT_A:
+               return POWER_DOMAIN_AUX_A;
+       case PORT_B:
+               return POWER_DOMAIN_AUX_B;
+       case PORT_C:
+               return POWER_DOMAIN_AUX_C;
+       case PORT_D:
+               return POWER_DOMAIN_AUX_D;
+       default:
+               WARN_ON_ONCE(1);
+               return 0;
+       }
+}
+
 static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 93bd9bf..a983b40 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1233,6 +1233,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
        power_domain = intel_display_port_power_domain(intel_encoder);
        intel_display_power_get(dev_priv, power_domain);
 
+       power_domain = intel_display_aux_power_domain(intel_encoder);
+       intel_display_power_get(dev_priv, power_domain);
+
        DRM_DEBUG_KMS("Turning eDP VDD on\n");
 
        if (!edp_have_panel_power(intel_dp))
@@ -1309,8 +1312,12 @@ static void edp_panel_vdd_off_sync(struct intel_dp 
*intel_dp)
 
        power_domain = intel_display_port_power_domain(intel_encoder);
        intel_display_power_put(dev_priv, power_domain);
+
+       power_domain = intel_display_aux_power_domain(intel_encoder);
+       intel_display_power_put(dev_priv, power_domain);
 }
 
+
 static void edp_panel_vdd_work(struct work_struct *__work)
 {
        struct intel_dp *intel_dp = container_of(to_delayed_work(__work),
@@ -3836,7 +3843,13 @@ g4x_dp_detect(struct intel_dp *intel_dp)
 static struct edid *
 intel_dp_get_edid(struct intel_dp *intel_dp)
 {
+       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct intel_encoder *intel_encoder = &intel_dig_port->base;
+       struct drm_device *dev = intel_encoder->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_connector *intel_connector = intel_dp->attached_connector;
+       enum intel_display_power_domain power_domain;
+       struct edid *edid;
 
        /* use cached edid if we have one */
        if (intel_connector->edid) {
@@ -3845,9 +3858,16 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
                        return NULL;
 
                return drm_edid_duplicate(intel_connector->edid);
-       } else
-               return drm_get_edid(&intel_connector->base,
-                                   &intel_dp->aux.ddc);
+       } else {
+               power_domain = intel_display_aux_power_domain(intel_encoder);
+               intel_display_power_get(dev_priv, power_domain);
+
+               edid = drm_get_edid(&intel_connector->base, &intel_dp->aux.ddc);
+
+               intel_display_power_put(dev_priv, power_domain);
+
+               return edid;
+       }
 }
 
 static void
@@ -3876,24 +3896,30 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
        intel_dp->has_audio = false;
 }
 
-static enum intel_display_power_domain
-intel_dp_power_get(struct intel_dp *dp)
+static void intel_dp_power_get(struct intel_dp *dp)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum intel_display_power_domain power_domain;
 
        power_domain = intel_display_port_power_domain(encoder);
        intel_display_power_get(to_i915(encoder->base.dev), power_domain);
 
-       return power_domain;
+       power_domain = intel_display_aux_power_domain(encoder);
+       intel_display_power_get(dev_priv, power_domain);
 }
 
-static void
-intel_dp_power_put(struct intel_dp *dp,
-                  enum intel_display_power_domain power_domain)
+static void intel_dp_power_put(struct intel_dp *dp)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(dp)->base;
-       intel_display_power_put(to_i915(encoder->base.dev), power_domain);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       enum intel_display_power_domain power_domain;
+
+       power_domain = intel_display_port_power_domain(encoder);
+       intel_display_power_put(dev_priv, power_domain);
+
+       power_domain = intel_display_aux_power_domain(encoder);
+       intel_display_power_put(dev_priv, power_domain);
 }
 
 static enum drm_connector_status
@@ -3904,7 +3930,6 @@ intel_dp_detect(struct drm_connector *connector, bool 
force)
        struct intel_encoder *intel_encoder = &intel_dig_port->base;
        struct drm_device *dev = connector->dev;
        enum drm_connector_status status;
-       enum intel_display_power_domain power_domain;
        bool ret;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
@@ -3918,7 +3943,7 @@ intel_dp_detect(struct drm_connector *connector, bool 
force)
                return connector_status_disconnected;
        }
 
-       power_domain = intel_dp_power_get(intel_dp);
+       intel_dp_power_get(intel_dp);
 
        /* Can't disconnect eDP, but you can close the lid... */
        if (is_edp(intel_dp))
@@ -3949,7 +3974,7 @@ intel_dp_detect(struct drm_connector *connector, bool 
force)
        status = connector_status_connected;
 
 out:
-       intel_dp_power_put(intel_dp, power_domain);
+       intel_dp_power_put(intel_dp);
        return status;
 }
 
@@ -3958,7 +3983,6 @@ intel_dp_force(struct drm_connector *connector)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
        struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
-       enum intel_display_power_domain power_domain;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, connector->name);
@@ -3967,11 +3991,11 @@ intel_dp_force(struct drm_connector *connector)
        if (connector->status != connector_status_connected)
                return;
 
-       power_domain = intel_dp_power_get(intel_dp);
+       intel_dp_power_get(intel_dp);
 
        intel_dp_set_edid(intel_dp);
 
-       intel_dp_power_put(intel_dp, power_domain);
+       intel_dp_power_put(intel_dp);
 
        if (intel_encoder->type != INTEL_OUTPUT_EDP)
                intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
@@ -4205,7 +4229,8 @@ intel_dp_hpd_pulse(struct intel_digital_port 
*intel_dig_port, bool long_hpd)
                      port_name(intel_dig_port->port),
                      long_hpd ? "long" : "short");
 
-       power_domain = intel_display_port_power_domain(intel_encoder);
+       power_domain = intel_display_aux_power_domain(intel_encoder);
+
        intel_display_power_get(dev_priv, power_domain);
 
        if (long_hpd) {
@@ -4648,6 +4673,9 @@ void intel_edp_panel_vdd_sanitize(struct intel_encoder 
*intel_encoder)
        power_domain = intel_display_port_power_domain(intel_encoder);
        intel_display_power_get(dev_priv, power_domain);
 
+       power_domain = intel_display_aux_power_domain(intel_encoder);
+       intel_display_power_get(dev_priv, power_domain);
+
        edp_panel_vdd_schedule_off(intel_dp);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9558f07..a407d04 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -916,6 +916,8 @@ void hsw_disable_ips(struct intel_crtc *crtc);
 void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder);
+enum intel_display_power_domain
+intel_display_aux_power_domain(struct intel_encoder *intel_encoder);
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
                                 struct intel_crtc_config *pipe_config);
 int intel_format_to_fourcc(int format);
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to