Commit f0ab43e6 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Imre Deak

drm/i915: Introduce a gmbus power domain

Currently the gmbus code uses intel_aux_display_runtime_get/put in an
effort to make sure the hardware is powered up sufficiently for gmbus.
That function only takes the runtime PM reference which on VLV/CHV/BXT
is not enough. We need the disp2d/pipe-a well on VLV/CHV and power well
2 on BXT. So add a new power domnain for gmbus and kill off the now
unused intel_aux_display_runtime_get/put. And change
intel_hdmi_set_edid() to use the gmbus power domain too since that's all
we need there.

Also toss in a BUILD_BUG_ON() to catch problems if we run out of
bits for power domains. We're already really close to the limit...

[Patrik: Add gmbus string to debugfs output]
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarPatrik Jakobsson <patrik.jakobsson@linux.intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1447084107-8521-5-git-send-email-patrik.jakobsson@linux.intel.com
parent 25f78f58
...@@ -2745,6 +2745,8 @@ static const char *power_domain_str(enum intel_display_power_domain domain) ...@@ -2745,6 +2745,8 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
return "AUX_C"; return "AUX_C";
case POWER_DOMAIN_AUX_D: case POWER_DOMAIN_AUX_D:
return "AUX_D"; return "AUX_D";
case POWER_DOMAIN_GMBUS:
return "GMBUS";
case POWER_DOMAIN_INIT: case POWER_DOMAIN_INIT:
return "INIT"; return "INIT";
default: default:
......
...@@ -199,6 +199,7 @@ enum intel_display_power_domain { ...@@ -199,6 +199,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_B, POWER_DOMAIN_AUX_B,
POWER_DOMAIN_AUX_C, POWER_DOMAIN_AUX_C,
POWER_DOMAIN_AUX_D, POWER_DOMAIN_AUX_D,
POWER_DOMAIN_GMBUS,
POWER_DOMAIN_INIT, POWER_DOMAIN_INIT,
POWER_DOMAIN_NUM, POWER_DOMAIN_NUM,
......
...@@ -1428,8 +1428,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, ...@@ -1428,8 +1428,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain); enum intel_display_power_domain domain);
void intel_display_power_put(struct drm_i915_private *dev_priv, void intel_display_power_put(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain); enum intel_display_power_domain domain);
void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv);
void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv);
void intel_runtime_pm_get(struct drm_i915_private *dev_priv); void intel_runtime_pm_get(struct drm_i915_private *dev_priv);
void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv); void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv);
void intel_runtime_pm_put(struct drm_i915_private *dev_priv); void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
......
...@@ -1346,21 +1346,17 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force) ...@@ -1346,21 +1346,17 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
{ {
struct drm_i915_private *dev_priv = to_i915(connector->dev); struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
struct intel_encoder *intel_encoder =
&hdmi_to_dig_port(intel_hdmi)->base;
enum intel_display_power_domain power_domain;
struct edid *edid = NULL; struct edid *edid = NULL;
bool connected = false; bool connected = false;
power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
intel_display_power_get(dev_priv, power_domain);
if (force) if (force)
edid = drm_get_edid(connector, edid = drm_get_edid(connector,
intel_gmbus_get_adapter(dev_priv, intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus)); intel_hdmi->ddc_bus));
intel_display_power_put(dev_priv, power_domain); intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
to_intel_connector(connector)->detect_edid = edid; to_intel_connector(connector)->detect_edid = edid;
if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
......
...@@ -483,7 +483,7 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -483,7 +483,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
int i = 0, inc, try = 0; int i = 0, inc, try = 0;
int ret = 0; int ret = 0;
intel_aux_display_runtime_get(dev_priv); intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
mutex_lock(&dev_priv->gmbus_mutex); mutex_lock(&dev_priv->gmbus_mutex);
if (bus->force_bit) { if (bus->force_bit) {
...@@ -595,7 +595,9 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -595,7 +595,9 @@ gmbus_xfer(struct i2c_adapter *adapter,
out: out:
mutex_unlock(&dev_priv->gmbus_mutex); mutex_unlock(&dev_priv->gmbus_mutex);
intel_aux_display_runtime_put(dev_priv);
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
return ret; return ret;
} }
......
...@@ -341,6 +341,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, ...@@ -341,6 +341,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
BIT(POWER_DOMAIN_AUX_C) | \ BIT(POWER_DOMAIN_AUX_C) | \
BIT(POWER_DOMAIN_AUDIO) | \ BIT(POWER_DOMAIN_AUDIO) | \
BIT(POWER_DOMAIN_VGA) | \ BIT(POWER_DOMAIN_VGA) | \
BIT(POWER_DOMAIN_GMBUS) | \
BIT(POWER_DOMAIN_INIT)) BIT(POWER_DOMAIN_INIT))
#define BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS ( \ #define BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS ( \
BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
...@@ -1438,6 +1439,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, ...@@ -1438,6 +1439,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT(POWER_DOMAIN_AUX_B) | \ BIT(POWER_DOMAIN_AUX_B) | \
BIT(POWER_DOMAIN_AUX_C) | \ BIT(POWER_DOMAIN_AUX_C) | \
BIT(POWER_DOMAIN_AUX_D) | \ BIT(POWER_DOMAIN_AUX_D) | \
BIT(POWER_DOMAIN_GMBUS) | \
BIT(POWER_DOMAIN_INIT)) BIT(POWER_DOMAIN_INIT))
#define HSW_DISPLAY_POWER_DOMAINS ( \ #define HSW_DISPLAY_POWER_DOMAINS ( \
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \ (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
...@@ -1814,6 +1816,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) ...@@ -1814,6 +1816,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
{ {
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
BUILD_BUG_ON(POWER_DOMAIN_NUM > 31);
mutex_init(&power_domains->lock); mutex_init(&power_domains->lock);
/* /*
...@@ -2085,36 +2089,6 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv) ...@@ -2085,36 +2089,6 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv)
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
} }
/**
* intel_aux_display_runtime_get - grab an auxiliary power domain reference
* @dev_priv: i915 device instance
*
* This function grabs a power domain reference for the auxiliary power domain
* (for access to the GMBUS and DP AUX blocks) and ensures that it and all its
* parents are powered up. Therefore users should only grab a reference to the
* innermost power domain they need.
*
* Any power domain reference obtained by this function must have a symmetric
* call to intel_aux_display_runtime_put() to release the reference again.
*/
void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv)
{
intel_runtime_pm_get(dev_priv);
}
/**
* intel_aux_display_runtime_put - release an auxiliary power domain reference
* @dev_priv: i915 device instance
*
* This function drops the auxiliary power domain reference obtained by
* intel_aux_display_runtime_get() and might power down the corresponding
* hardware block right away if this is the last reference.
*/
void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv)
{
intel_runtime_pm_put(dev_priv);
}
/** /**
* intel_runtime_pm_get - grab a runtime pm reference * intel_runtime_pm_get - grab a runtime pm reference
* @dev_priv: i915 device instance * @dev_priv: i915 device instance
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment