[PATCH 1/2] callbacks-on-vblank
Chris Wilson
chris at chris-wilson.co.uk
Thu Aug 17 10:49:49 UTC 2017
---
drivers/gpu/drm/i915/i915_irq.c | 46 ++++++++++++++++++++++++++++++------
drivers/gpu/drm/i915/intel_display.c | 2 ++
drivers/gpu/drm/i915/intel_drv.h | 6 +++++
3 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e21ce9c18b6e..7acb31f57352 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1767,6 +1767,38 @@ static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
spin_unlock(&dev_priv->irq_lock);
}
+static void intel_handle_vblank(struct drm_i915_private *i915, int pipe)
+{
+ struct intel_crtc *crtc = i915->pipe_to_crtc_mapping[pipe];
+
+ drm_handle_vblank(&i915->drm, pipe);
+
+ spin_lock(&crtc->vblank_wq.lock);
+ if (waitqueue_active(&crtc->vblank_wq)) {
+ wake_up_all_locked(&crtc->vblank_wq);
+ if (!waitqueue_active(&crtc->vblank_wq))
+ drm_crtc_vblank_put(&crtc->base);
+ }
+ spin_unlock(&crtc->vblank_wq.lock);
+}
+
+int intel_crtc_add_vblank_wait(struct intel_crtc *crtc,
+ wait_queue_entry_t *wait)
+{
+ unsigned long flags;
+ int err;
+
+ err = 0;
+ spin_lock_irqsave(&crtc->vblank_wq.lock, flags);
+ if (!waitqueue_active(&crtc->vblank_wq))
+ err = drm_crtc_vblank_get(&crtc->base);
+ if (!err)
+ __add_wait_queue(&crtc->vblank_wq, wait);
+ spin_unlock_irqrestore(&crtc->vblank_wq.lock, flags);
+
+ return err;
+}
+
static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
u32 pipe_stats[I915_MAX_PIPES])
{
@@ -1774,7 +1806,7 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
for_each_pipe(dev_priv, pipe) {
if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -2227,7 +2259,7 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
for_each_pipe(dev_priv, pipe) {
if (de_iir & DE_PIPE_VBLANK(pipe))
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
@@ -2273,7 +2305,7 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
for_each_pipe(dev_priv, pipe) {
if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
}
/* check event from PCH */
@@ -2469,7 +2501,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
if (iir & GEN8_PIPE_VBLANK)
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
hsw_pipe_crc_irq_handler(dev_priv, pipe);
@@ -3668,7 +3700,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
plane = !plane;
if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -3830,7 +3862,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
plane = !plane;
if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
@@ -4056,7 +4088,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
for_each_pipe(dev_priv, pipe) {
if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
- drm_handle_vblank(&dev_priv->drm, pipe);
+ intel_handle_vblank(dev_priv, pipe);
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 0e93ec201fe3..cd9837694e99 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13389,6 +13389,8 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
if (!intel_crtc)
return -ENOMEM;
+ init_waitqueue_head(&intel_crtc->vblank_wq);
+
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
if (!crtc_state) {
ret = -ENOMEM;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fa47285918f4..832985dbb38d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -838,6 +838,8 @@ struct intel_crtc {
/* scalers available on this crtc */
int num_scalers;
+
+ struct wait_queue_head vblank_wq;
};
struct intel_plane {
@@ -1980,4 +1982,8 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
#define intel_crtc_set_crc_source NULL
#endif
extern const struct file_operations i915_display_crc_ctl_fops;
+
+int intel_crtc_add_vblank_wait(struct intel_crtc *crtc,
+ wait_queue_entry_t *wait);
+
#endif /* __INTEL_DRV_H__ */
--
2.14.1
More information about the Intel-gfx-trybot
mailing list