From 4781f20f29926ec68715f5cc930273a79fc0a9eb Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Mon, 28 Sep 2009 15:41:08 -0700 Subject: [PATCH 1/6] drm/i915: Don't call intel_update_fbc from intel_crtc_cursor_set Commit 74dff282 exposed this unnecessary call by causing a change in the failure path on i965 where framebuffer compression will be turned on and off on every cursor update. If you don't have the xf86-video-intel fix to avoid the blinking cursor effect, this is very slow. Symptoms were a far more noticeable cursor blink with every cursor image change combined with severe slowdown for animated cursors. Signed-off-by: Brian Rogers Acked-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 93ff6c03733e..7a5fb7932c0e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3095,7 +3095,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, struct drm_gem_object *bo; struct drm_i915_gem_object *obj_priv; int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; uint32_t temp = I915_READ(control); @@ -3182,9 +3181,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, drm_gem_object_unreference(intel_crtc->cursor_bo); } - if ((IS_I965G(dev) || plane == 0)) - intel_update_fbc(crtc, &crtc->mode); - mutex_unlock(&dev->struct_mutex); intel_crtc->cursor_addr = addr; From 4f49be546806bf3839daa0601e1c2d4342c93359 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 24 Sep 2009 00:23:33 +0100 Subject: [PATCH 2/6] drm/i915: Record device minor rather than pointer in TRACE_EVENT Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_trace.h | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 5567a40816f3..908b3c4d8cf7 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -158,16 +158,16 @@ TRACE_EVENT(i915_gem_request_submit, TP_ARGS(dev, seqno), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) __field(u32, seqno) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; __entry->seqno = seqno; ), - TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) + TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) ); TRACE_EVENT(i915_gem_request_flush, @@ -178,20 +178,20 @@ TRACE_EVENT(i915_gem_request_flush, TP_ARGS(dev, seqno, flush_domains, invalidate_domains), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) __field(u32, seqno) __field(u32, flush_domains) __field(u32, invalidate_domains) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; __entry->seqno = seqno; __entry->flush_domains = flush_domains; __entry->invalidate_domains = invalidate_domains; ), - TP_printk("dev=%p, seqno=%u, flush=%04x, invalidate=%04x", + TP_printk("dev=%u, seqno=%u, flush=%04x, invalidate=%04x", __entry->dev, __entry->seqno, __entry->flush_domains, __entry->invalidate_domains) ); @@ -204,16 +204,16 @@ TRACE_EVENT(i915_gem_request_complete, TP_ARGS(dev, seqno), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) __field(u32, seqno) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; __entry->seqno = seqno; ), - TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) + TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) ); TRACE_EVENT(i915_gem_request_retire, @@ -223,16 +223,16 @@ TRACE_EVENT(i915_gem_request_retire, TP_ARGS(dev, seqno), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) __field(u32, seqno) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; __entry->seqno = seqno; ), - TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) + TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) ); TRACE_EVENT(i915_gem_request_wait_begin, @@ -242,16 +242,16 @@ TRACE_EVENT(i915_gem_request_wait_begin, TP_ARGS(dev, seqno), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) __field(u32, seqno) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; __entry->seqno = seqno; ), - TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) + TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) ); TRACE_EVENT(i915_gem_request_wait_end, @@ -261,16 +261,16 @@ TRACE_EVENT(i915_gem_request_wait_end, TP_ARGS(dev, seqno), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) __field(u32, seqno) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; __entry->seqno = seqno; ), - TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) + TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) ); TRACE_EVENT(i915_ring_wait_begin, @@ -280,14 +280,14 @@ TRACE_EVENT(i915_ring_wait_begin, TP_ARGS(dev), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; ), - TP_printk("dev=%p", __entry->dev) + TP_printk("dev=%u", __entry->dev) ); TRACE_EVENT(i915_ring_wait_end, @@ -297,14 +297,14 @@ TRACE_EVENT(i915_ring_wait_end, TP_ARGS(dev), TP_STRUCT__entry( - __field(struct drm_device *, dev) + __field(u32, dev) ), TP_fast_assign( - __entry->dev = dev; + __entry->dev = dev->primary->index; ), - TP_printk("dev=%p", __entry->dev) + TP_printk("dev=%u", __entry->dev) ); #endif /* _I915_TRACE_H_ */ From 8f0dc5bf17dfd947bf7b2cd07a8b1f43e72fb750 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 24 Sep 2009 00:43:17 +0100 Subject: [PATCH 3/6] drm/i915: batch submit seqno off-by-one. We increment the seqno number between submitting the batch buffer and the flush/interrupt that demarcates its end, so the tracepoint needs to reference the incremented value to match the completion event. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 40727d4c2919..b5f9df230d09 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3352,7 +3352,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev, exec_start = (uint32_t) exec_offset + exec->batch_start_offset; exec_len = (uint32_t) exec->batch_len; - trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno); + trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); count = nbox ? nbox : 1; From 9d34e5db07303c9609053e2e651aa6d1fc74e923 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 24 Sep 2009 05:26:06 +0100 Subject: [PATCH 4/6] drm/i915: Enable irq to trace batch buffer completion. If we trigger a tracepoint for batch buffer submission, it is a reasonable assumption that we wish to also trace the batch buffer completion. So in order to capture the completion events, we need to enable irqs... However, we cannot rely on the completion event to disable the irq later, so we defer the irq disable to the retire request. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 8 +++++++- drivers/gpu/drm/i915/i915_irq.c | 10 ++++++++++ drivers/gpu/drm/i915/i915_trace.h | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 45d507ebd3ff..92aeb918e0c0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1468,6 +1468,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) spin_lock_init(&dev_priv->user_irq_lock); spin_lock_init(&dev_priv->error_lock); dev_priv->user_irq_refcount = 0; + dev_priv->trace_irq_seqno = 0; ret = drm_vblank_init(dev, I915_NUM_PIPE); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b24b2d145b75..6035d3dae851 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -202,6 +202,7 @@ typedef struct drm_i915_private { spinlock_t user_irq_lock; /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ int user_irq_refcount; + u32 trace_irq_seqno; /** Cached value of IMR to avoid reads in updating the bitfield */ u32 irq_mask_reg; u32 pipestat[2]; @@ -665,6 +666,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, extern int i915_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); void i915_user_irq_get(struct drm_device *dev); +void i915_trace_irq_get(struct drm_device *dev, u32 seqno); void i915_user_irq_put(struct drm_device *dev); extern void i915_enable_interrupt (struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b5f9df230d09..abfc27b0c2ea 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1770,7 +1770,7 @@ i915_gem_retire_requests(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; - if (!dev_priv->hw_status_page) + if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list)) return; seqno = i915_get_gem_seqno(dev); @@ -1794,6 +1794,12 @@ i915_gem_retire_requests(struct drm_device *dev) } else break; } + + if (unlikely (dev_priv->trace_irq_seqno && + i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { + i915_user_irq_put(dev); + dev_priv->trace_irq_seqno = 0; + } } void diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4dfeec7cdd42..c3ceffa46ea0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -725,6 +725,16 @@ void i915_user_irq_put(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } +void i915_trace_irq_get(struct drm_device *dev, u32 seqno) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + + if (dev_priv->trace_irq_seqno == 0) + i915_user_irq_get(dev); + + dev_priv->trace_irq_seqno = seqno; +} + static int i915_wait_irq(struct drm_device * dev, int irq_nr) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 908b3c4d8cf7..01840d9bc38f 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -165,6 +165,7 @@ TRACE_EVENT(i915_gem_request_submit, TP_fast_assign( __entry->dev = dev->primary->index; __entry->seqno = seqno; + i915_trace_irq_get(dev, seqno); ), TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) From 0d0884cee3099ec1271a5d379c39b66de1e31923 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 29 Sep 2009 16:31:49 +0800 Subject: [PATCH 5/6] drm/i915: Multiply the refresh by 1000 in TV mode validatiion As of 559ee21d261a54c42594ef9405d27e9008eedf44 the actual refresh rate is returned by the function of drm_mode_vrefresh, so multiply the refresh rate by 1000 in TV mode validation. At the same time the error is expanded from 10 to 1000. Signed-off-by: Zhao Yakui Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_tv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index c64eab493fb0..9ca917931afb 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1082,7 +1082,8 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); /* Ensure TV refresh is close to desired refresh */ - if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10) + if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) + < 1000) return MODE_OK; return MODE_CLOCK_RANGE; } From 8d91104aac6e21e6ca2a56124e2e47b0db043ea8 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 23 Sep 2009 15:08:29 -0400 Subject: [PATCH 6/6] drm/i915: Initialize HDMI outputs as HDMI connectors, not DVI. Even if the physical output connector is DVI, calling it HDMI tells the user that there's HDMI audio signaling support. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index fa304e136010..663ab6de0b58 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -223,7 +223,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) connector = &intel_output->base; drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_DVID); + DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); intel_output->type = INTEL_OUTPUT_HDMI;