summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorDaniel Vetter2012-12-01 13:53:48 +0100
committerDaniel Vetter2012-12-06 13:18:00 +0100
commit9ee32fea5fe810ec06af3a15e4c65478de56d4f5 (patch)
treebd12375772bcd86ec85e3236d6072aef7e99da40 /drivers/gpu/drm/i915/i915_irq.c
parentdrm/i915: wire up do aux channel done interrupt (diff)
downloadkernel-qcow2-linux-9ee32fea5fe810ec06af3a15e4c65478de56d4f5.tar.gz
kernel-qcow2-linux-9ee32fea5fe810ec06af3a15e4c65478de56d4f5.tar.xz
kernel-qcow2-linux-9ee32fea5fe810ec06af3a15e4c65478de56d4f5.zip
drm/i915: irq-drive the dp aux communication
At least on the platforms that have a dp aux irq and also have it enabled - vlvhsw should have one, too. But I don't have a machine to test this on. Judging from docs there's no dp aux interrupt for gm45. Also, I only have an ivb cpu edp machine, so the dp aux A code for snb/ilk is untested. For dpcd probing when nothing is connected it slashes about 5ms of cpu time (cpu time is now negligible), which agrees with 3 * 5 400 usec timeouts. A previous version of this patch increases the time required to go through the dp_detect cycle (which includes reading the edid) from around 33 ms to around 40 ms. Experiments indicated that this is purely due to the irq latency - the hw doesn't allow us to queue up dp aux transactions and hence irq latency directly affects throughput. gmbus is much better, there we have a 8 byte buffer, and we get the irq once another 4 bytes can be queued up. But by using the pm_qos interface to request the lowest possible cpu wake-up latency this slowdown completely disappeared. Since all our output detection logic is single-threaded with the mode_config mutex right now anyway, I've decide not ot play fancy and to just reuse the gmbus wait queue. But this would definitely prep the way to run dp detection on different ports in parallel v2: Add a timeout for dp aux transfers when using interrupts - the hw _does_ prevent this with the hw-based 400 usec timeout, but if the irq somehow doesn't arrive we're screwed. Lesson learned while developing this ;-) v3: While at it also convert the busy-loop to wait_for_atomic, so that we don't run the risk of an infinite loop any more. v4: Ensure we have the smallest possible irq latency by using the pm_qos interface. v5: Add a comment to the code to explain why we frob pm_qos. Suggested by Chris Wilson. v6: Disable dp irq for vlv, that's easier than trying to get at docs and hw. v7: Squash in a fix for Haswell that Paulo Zanoni tracked down - the dp aux registers aren't at a fixed offset any more, but can be on the PCH while the DP port is on the cpu die. Reviewed-by: Imre Deak <imre.deak@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 1e245e501e5a..58bb11b58796 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -536,7 +536,11 @@ static void gmbus_irq_handler(struct drm_device *dev)
static void dp_aux_irq_handler(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
DRM_DEBUG_DRIVER("AUX channel interrupt\n");
+
+ wake_up_all(&dev_priv->gmbus_wait_queue);
}
static irqreturn_t valleyview_irq_handler(int irq, void *arg)
@@ -2732,6 +2736,8 @@ void intel_irq_init(struct drm_device *dev)
setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
(unsigned long) dev);
+ pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, 0);
+
dev->driver->get_vblank_counter = i915_get_vblank_counter;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {