[Intel-gfx] [PATCH 72/89] drm/i915/skl: Enable/disable power well for aux transaction
Damien Lespiau
damien.lespiau at intel.com
Thu Sep 4 13:27:38 CEST 2014
From: Satheeshakrishna M <satheeshakrishna.m at intel.com>
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 <satheeshakrishna.m at intel.com> (v4, v9)
Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
---
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
More information about the Intel-gfx
mailing list