[Intel-gfx] [PATCHv5] drm/i915: use waitqueue in wait for vblank
Arun R Murthy
arun.r.murthy at intel.com
Wed May 21 09:39:58 CEST 2014
Instead of using sleep functions in wait for vblank, which wakes up on
sleep timeout aften, thereby scheduler provoking scheduler. Hence use
waitqueue in wait for vblank.
Signed-off-by: Arun R Murthy <arun.r.murthy at intel.com>
---
drivers/gpu/drm/i915/i915_dma.c | 2 ++
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_irq.c | 17 +++++++++++++----
drivers/gpu/drm/i915/intel_display.c | 10 ++++++----
4 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 258b1be..896620c 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1506,6 +1506,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
mutex_init(&dev_priv->dpio_lock);
mutex_init(&dev_priv->modeset_restore_lock);
+ init_waitqueue_head(&dev_priv->wait_vblank);
+
intel_pm_setup(dev);
intel_display_crc_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 728b9c3..449bfef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1590,6 +1590,7 @@ typedef struct drm_i915_private {
struct i915_dri1_state dri1;
/* Old ums support infrastructure, same warning applies. */
struct i915_ums_state ums;
+ wait_queue_head_t wait_vblank;
} drm_i915_private_t;
static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 56edff3..f97f0fe 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1513,8 +1513,11 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
for_each_pipe(pipe) {
- if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+ if (pipe_stats[pipe] &
+ PIPE_START_VBLANK_INTERRUPT_STATUS) {
drm_handle_vblank(dev, pipe);
+ wake_up_interruptible(&dev_priv->wait_vblank);
+ }
if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
intel_prepare_page_flip(dev, pipe);
@@ -3269,8 +3272,10 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
plane = !plane;
if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i8xx_handle_vblank(dev, plane, pipe, iir))
+ i8xx_handle_vblank(dev, plane, pipe, iir)) {
flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+ wake_up_interruptible(&dev_priv->wait_vblank);
+ }
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev, pipe);
@@ -3464,8 +3469,10 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
plane = !plane;
if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i915_handle_vblank(dev, plane, pipe, iir))
+ i915_handle_vblank(dev, plane, pipe, iir)) {
flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+ wake_up_interruptible(&dev_priv->wait_vblank);
+ }
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
@@ -3709,8 +3716,10 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
for_each_pipe(pipe) {
if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
- i915_handle_vblank(dev, pipe, pipe, iir))
+ i915_handle_vblank(dev, pipe, pipe, iir)) {
flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
+ wake_up_interruptible(&dev_priv->wait_vblank);
+ }
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4d4a0d9..e1eb564 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -757,12 +757,14 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
static void g4x_wait_for_vblank(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 frame, frame_reg = PIPE_FRMCOUNT_GM45(pipe);
+ u32 vblank_cnt;
- frame = I915_READ(frame_reg);
+ vblank_cnt = drm_vblank_count(dev, pipe);
- if (wait_for(I915_READ_NOTRACE(frame_reg) != frame, 50))
- DRM_DEBUG_KMS("vblank wait timed out\n");
+ /* TODO: get the vblank time dynamically or from platform data */
+ wait_event_interruptible_timeout(dev_priv->wait_vblank,
+ (vblank_cnt != drm_vblank_count(dev, pipe)),
+ msecs_to_jiffies(16));
}
/**
--
1.7.9.5
More information about the Intel-gfx
mailing list