From: Paulo Zanoni <przanoni@gmail.com>
To: intel-gfx@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 5/8] drm/i915: avoid waking up from PC8 on GMBUS operations
Date: Mon, 29 Jul 2013 17:48:24 -0300 [thread overview]
Message-ID: <1375130907-4054-6-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <1375130907-4054-1-git-send-email-przanoni@gmail.com>
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
If we're already allowing PC8, just don't use the IRQs, so we won't
need to wake from PC8. Waking up from PC8 is a slow thing, so avoid it
when we can.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_i2c.c | 75 ++++++++++++++++++++++++++--------------
1 file changed, 50 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index d1c1e0f7..2f35c10 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -203,24 +203,18 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
algo->data = bus;
}
-/*
- * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI
- * mode. This results in spurious interrupt warnings if the legacy irq no. is
- * shared with another device. The kernel then disables that interrupt source
- * and so prevents the other device from working properly.
- */
-#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
static int
gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
u32 gmbus2_status,
- u32 gmbus4_irq_en)
+ u32 gmbus4_irq_en,
+ bool use_irq)
{
int i;
int reg_offset = dev_priv->gpio_mmio_base;
u32 gmbus2 = 0;
DEFINE_WAIT(wait);
- if (!HAS_GMBUS_IRQ(dev_priv->dev))
+ if (!use_irq)
gmbus4_irq_en = 0;
/* Important: The hw handles only the first bit, so set only one! Since
@@ -250,14 +244,14 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
}
static int
-gmbus_wait_idle(struct drm_i915_private *dev_priv)
+gmbus_wait_idle(struct drm_i915_private *dev_priv, bool use_irq)
{
int ret;
int reg_offset = dev_priv->gpio_mmio_base;
#define C ((I915_READ_NOTRACE(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0)
- if (!HAS_GMBUS_IRQ(dev_priv->dev))
+ if (!use_irq)
return wait_for(C, 10);
/* Important: The hw handles only the first bit, so set only one! */
@@ -277,7 +271,7 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
static int
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
- u32 gmbus1_index)
+ u32 gmbus1_index, bool use_irq)
{
int reg_offset = dev_priv->gpio_mmio_base;
u16 len = msg->len;
@@ -294,7 +288,7 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
u32 val, loop = 0;
ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
- GMBUS_HW_RDY_EN);
+ GMBUS_HW_RDY_EN, use_irq);
if (ret)
return ret;
@@ -309,7 +303,8 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
}
static int
-gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
+gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
+ bool use_irq)
{
int reg_offset = dev_priv->gpio_mmio_base;
u16 len = msg->len;
@@ -339,7 +334,7 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
I915_WRITE(GMBUS3 + reg_offset, val);
ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
- GMBUS_HW_RDY_EN);
+ GMBUS_HW_RDY_EN, use_irq);
if (ret)
return ret;
}
@@ -359,7 +354,8 @@ gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
}
static int
-gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
+gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs,
+ bool use_irq)
{
int reg_offset = dev_priv->gpio_mmio_base;
u32 gmbus1_index = 0;
@@ -377,7 +373,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
if (gmbus5)
I915_WRITE(GMBUS5 + reg_offset, gmbus5);
- ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
+ ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index, use_irq);
/* Clear GMBUS5 after each index transfer */
if (gmbus5)
@@ -386,6 +382,31 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
return ret;
}
+static bool gmbus_use_irq(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ bool ret;
+
+ /*
+ * gmbus on gen4 seems to be able to generate legacy interrupts even
+ * when in MSI mode. This results in spurious interrupt warnings if the
+ * legacy irq no. is shared with another device. The kernel then
+ * disables that interrupt source and so prevents the other device from
+ * working properly.
+ */
+ if (INTEL_INFO(dev)->gen <= 4)
+ return false;
+
+ /* In case we're already allowing PC8, just don't use IRQs, so we won't
+ * need to call intel_aux_display_runtime_get and then we won't wake up
+ * from PC8. */
+ mutex_lock(&dev_priv->pc8.lock);
+ ret = (dev_priv->pc8.forbid_refcnt != 0);
+ mutex_unlock(&dev_priv->pc8.lock);
+
+ return ret;
+}
+
static int
gmbus_xfer(struct i2c_adapter *adapter,
struct i2c_msg *msgs,
@@ -397,8 +418,10 @@ gmbus_xfer(struct i2c_adapter *adapter,
struct drm_i915_private *dev_priv = bus->dev_priv;
int i, reg_offset;
int ret = 0;
+ bool use_irq = gmbus_use_irq(dev_priv->dev);
- intel_aux_display_runtime_get(dev_priv);
+ if (use_irq)
+ intel_aux_display_runtime_get(dev_priv);
mutex_lock(&dev_priv->gmbus_mutex);
if (bus->force_bit) {
@@ -412,12 +435,13 @@ gmbus_xfer(struct i2c_adapter *adapter,
for (i = 0; i < num; i++) {
if (gmbus_is_index_read(msgs, i, num)) {
- ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
+ ret = gmbus_xfer_index_read(dev_priv, &msgs[i],
+ use_irq);
i += 1; /* set i to the index of the read xfer */
} else if (msgs[i].flags & I2C_M_RD) {
- ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
+ ret = gmbus_xfer_read(dev_priv, &msgs[i], 0, use_irq);
} else {
- ret = gmbus_xfer_write(dev_priv, &msgs[i]);
+ ret = gmbus_xfer_write(dev_priv, &msgs[i], use_irq);
}
if (ret == -ETIMEDOUT)
@@ -426,7 +450,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
goto clear_err;
ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_WAIT_PHASE,
- GMBUS_HW_WAIT_EN);
+ GMBUS_HW_WAIT_EN, use_irq);
if (ret == -ENXIO)
goto clear_err;
if (ret)
@@ -443,7 +467,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
* We will re-enable it at the start of the next xfer,
* till then let it sleep.
*/
- if (gmbus_wait_idle(dev_priv)) {
+ if (gmbus_wait_idle(dev_priv, use_irq)) {
DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n",
adapter->name);
ret = -ETIMEDOUT;
@@ -467,7 +491,7 @@ clear_err:
* it's slow responding and only answers on the 2nd retry.
*/
ret = -ENXIO;
- if (gmbus_wait_idle(dev_priv)) {
+ if (gmbus_wait_idle(dev_priv, use_irq)) {
DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n",
adapter->name);
ret = -ETIMEDOUT;
@@ -498,7 +522,8 @@ timeout:
out:
mutex_unlock(&dev_priv->gmbus_mutex);
- intel_aux_display_runtime_put(dev_priv);
+ if (use_irq)
+ intel_aux_display_runtime_put(dev_priv);
return ret;
}
--
1.8.1.2
next prev parent reply other threads:[~2013-07-29 20:48 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-29 20:48 [PATCH 0/8] Allow Package C8+ Paulo Zanoni
2013-07-29 20:48 ` [PATCH 1/8] drm/i915: add the FCLK case to intel_ddi_get_cdclk_freq Paulo Zanoni
2013-07-29 20:48 ` [PATCH 2/8] drm/i915: don't disable/reenable IVB error interrupts when not needed Paulo Zanoni
2013-07-30 9:46 ` Chris Wilson
2013-08-01 17:16 ` Paulo Zanoni
2013-07-29 20:48 ` [PATCH 3/8] drm/i915: allow package C8+ states on Haswell (disabled) Paulo Zanoni
2013-07-29 21:42 ` Chris Wilson
2013-07-31 14:24 ` Paulo Zanoni
2013-07-31 15:01 ` Chris Wilson
2013-07-31 16:47 ` Paulo Zanoni
2013-07-29 23:11 ` Chris Wilson
2013-07-29 20:48 ` [PATCH 4/8] drm/i915: avoid waking up from PC8 on DP AUX operations Paulo Zanoni
2013-07-30 9:40 ` Chris Wilson
2013-07-31 14:31 ` Paulo Zanoni
2013-07-31 14:45 ` Chris Wilson
2013-07-29 20:48 ` Paulo Zanoni [this message]
2013-07-30 9:30 ` [PATCH 5/8] drm/i915: avoid waking up from PC8 on GMBUS operations Chris Wilson
2013-08-05 6:07 ` Daniel Vetter
2013-08-05 13:17 ` Paulo Zanoni
2013-07-29 20:48 ` [PATCH 6/8] drm/i915: silence message about the DDI buffers Paulo Zanoni
2013-07-29 20:48 ` [PATCH 7/8] drm/i915: add i915_pc8_status debugfs file Paulo Zanoni
2013-07-29 20:48 ` [PATCH 8/8] drm/i915: allow Package C8+ by default Paulo Zanoni
2013-07-30 9:25 ` Chris Wilson
2013-07-29 20:53 ` [PATCH i-g-t] tests: add pc8 Paulo Zanoni
2013-08-05 6:05 ` Daniel Vetter
2013-08-05 13:42 ` Paulo Zanoni
2013-08-05 15:35 ` Daniel Vetter
2013-08-06 19:33 ` Paulo Zanoni
2013-08-06 20:11 ` Daniel Vetter
2013-08-06 20:18 ` Daniel Vetter
2013-08-06 20:43 ` Paulo Zanoni
2013-08-13 21:48 ` Daniel Vetter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1375130907-4054-6-git-send-email-przanoni@gmail.com \
--to=przanoni@gmail.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=paulo.r.zanoni@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).