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: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1447084107-8521-5-git-send-email-patrik.jakobsson@linux.intel.com
This commit is contained in:
parent
25f78f58e5
commit
f0ab43e6c3
|
@ -2745,6 +2745,8 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
|
|||
return "AUX_C";
|
||||
case POWER_DOMAIN_AUX_D:
|
||||
return "AUX_D";
|
||||
case POWER_DOMAIN_GMBUS:
|
||||
return "GMBUS";
|
||||
case POWER_DOMAIN_INIT:
|
||||
return "INIT";
|
||||
default:
|
||||
|
|
|
@ -199,6 +199,7 @@ enum intel_display_power_domain {
|
|||
POWER_DOMAIN_AUX_B,
|
||||
POWER_DOMAIN_AUX_C,
|
||||
POWER_DOMAIN_AUX_D,
|
||||
POWER_DOMAIN_GMBUS,
|
||||
POWER_DOMAIN_INIT,
|
||||
|
||||
POWER_DOMAIN_NUM,
|
||||
|
|
|
@ -1428,8 +1428,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
|
|||
enum intel_display_power_domain domain);
|
||||
void intel_display_power_put(struct drm_i915_private *dev_priv,
|
||||
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_noresume(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)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
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;
|
||||
bool connected = false;
|
||||
|
||||
power_domain = intel_display_port_power_domain(intel_encoder);
|
||||
intel_display_power_get(dev_priv, power_domain);
|
||||
intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
|
||||
if (force)
|
||||
edid = drm_get_edid(connector,
|
||||
intel_gmbus_get_adapter(dev_priv,
|
||||
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;
|
||||
if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
|
||||
|
|
|
@ -483,7 +483,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
|
|||
int i = 0, inc, try = 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);
|
||||
|
||||
if (bus->force_bit) {
|
||||
|
@ -595,7 +595,9 @@ timeout:
|
|||
|
||||
out:
|
||||
mutex_unlock(&dev_priv->gmbus_mutex);
|
||||
intel_aux_display_runtime_put(dev_priv);
|
||||
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -341,6 +341,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
|
|||
BIT(POWER_DOMAIN_AUX_C) | \
|
||||
BIT(POWER_DOMAIN_AUDIO) | \
|
||||
BIT(POWER_DOMAIN_VGA) | \
|
||||
BIT(POWER_DOMAIN_GMBUS) | \
|
||||
BIT(POWER_DOMAIN_INIT))
|
||||
#define BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS ( \
|
||||
BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
|
||||
|
@ -1438,6 +1439,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
|
|||
BIT(POWER_DOMAIN_AUX_B) | \
|
||||
BIT(POWER_DOMAIN_AUX_C) | \
|
||||
BIT(POWER_DOMAIN_AUX_D) | \
|
||||
BIT(POWER_DOMAIN_GMBUS) | \
|
||||
BIT(POWER_DOMAIN_INIT))
|
||||
#define HSW_DISPLAY_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)
|
|||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
|
||||
BUILD_BUG_ON(POWER_DOMAIN_NUM > 31);
|
||||
|
||||
mutex_init(&power_domains->lock);
|
||||
|
||||
/*
|
||||
|
@ -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_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
|
||||
* @dev_priv: i915 device instance
|
||||
|
|
Loading…
Reference in New Issue