mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 02:09:42 +00:00
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>
[Cherry-picked from drm-intel-next-queued f0ab43e6
(Imre)]
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1448643329-18675-3-git-send-email-imre.deak@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
This commit is contained in:
parent
a781ce79d5
commit
ac9b823655
6 changed files with 13 additions and 40 deletions
|
@ -2734,6 +2734,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,
|
||||
|
|
|
@ -1379,8 +1379,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);
|
||||
|
|
|
@ -1335,21 +1335,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 @@ gmbus_xfer(struct i2c_adapter *adapter,
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -362,6 +362,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 | \
|
||||
|
@ -1483,6 +1484,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) | \
|
||||
|
@ -1845,6 +1847,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
|
|||
i915.disable_power_well = sanitize_disable_power_well_option(dev_priv,
|
||||
i915.disable_power_well);
|
||||
|
||||
BUILD_BUG_ON(POWER_DOMAIN_NUM > 31);
|
||||
|
||||
mutex_init(&power_domains->lock);
|
||||
|
||||
/*
|
||||
|
@ -2063,36 +2067,6 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
|
|||
power_domains->initializing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 a new issue