summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c32
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.h1
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c12
3 files changed, 27 insertions, 18 deletions
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index d88a3b9d59cc..3c628e43bf25 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -185,25 +185,29 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm)
static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
{
- struct drm_pending_vblank_event *event;
struct drm_device *drm = state->dev;
struct malidp_drm *malidp = drm->dev_private;
- if (malidp->crtc.enabled) {
- /* only set config_valid if the CRTC is enabled */
- if (malidp_set_and_wait_config_valid(drm))
- DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n");
- }
+ malidp->event = malidp->crtc.state->event;
+ malidp->crtc.state->event = NULL;
- event = malidp->crtc.state->event;
- if (event) {
- malidp->crtc.state->event = NULL;
+ if (malidp->crtc.state->active) {
+ /*
+ * if we have an event to deliver to userspace, make sure
+ * the vblank is enabled as we are sending it from the IRQ
+ * handler.
+ */
+ if (malidp->event)
+ drm_crtc_vblank_get(&malidp->crtc);
+ /* only set config_valid if the CRTC is enabled */
+ if (malidp_set_and_wait_config_valid(drm) < 0)
+ DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n");
+ } else if (malidp->event) {
+ /* CRTC inactive means vblank IRQ is disabled, send event directly */
spin_lock_irq(&drm->event_lock);
- if (drm_crtc_vblank_get(&malidp->crtc) == 0)
- drm_crtc_arm_vblank_event(&malidp->crtc, event);
- else
- drm_crtc_send_vblank_event(&malidp->crtc, event);
+ drm_crtc_send_vblank_event(&malidp->crtc, malidp->event);
+ malidp->event = NULL;
spin_unlock_irq(&drm->event_lock);
}
drm_atomic_helper_commit_hw_done(state);
@@ -232,8 +236,6 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
malidp_atomic_commit_hw_done(state);
- drm_atomic_helper_wait_for_vblanks(drm, state);
-
pm_runtime_put(drm->dev);
drm_atomic_helper_cleanup_planes(drm, state);
diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h
index e0d12c9fc6b8..c2375bb49619 100644
--- a/drivers/gpu/drm/arm/malidp_drv.h
+++ b/drivers/gpu/drm/arm/malidp_drv.h
@@ -22,6 +22,7 @@ struct malidp_drm {
struct malidp_hw_device *dev;
struct drm_crtc crtc;
wait_queue_head_t wq;
+ struct drm_pending_vblank_event *event;
atomic_t config_valid;
u32 core_id;
};
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 2bfb542135ac..8abd335ec313 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -782,9 +782,15 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
/* first handle the config valid IRQ */
dc_status = malidp_hw_read(hwdev, hw->map.dc_base + MALIDP_REG_STATUS);
if (dc_status & hw->map.dc_irq_map.vsync_irq) {
- /* we have a page flip event */
- atomic_set(&malidp->config_valid, 1);
malidp_hw_clear_irq(hwdev, MALIDP_DC_BLOCK, dc_status);
+ /* do we have a page flip event? */
+ if (malidp->event != NULL) {
+ spin_lock(&drm->event_lock);
+ drm_crtc_send_vblank_event(&malidp->crtc, malidp->event);
+ malidp->event = NULL;
+ spin_unlock(&drm->event_lock);
+ }
+ atomic_set(&malidp->config_valid, 1);
ret = IRQ_WAKE_THREAD;
}
@@ -794,7 +800,7 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
mask = malidp_hw_read(hwdev, MALIDP_REG_MASKIRQ);
status &= mask;
- if (status & de->vsync_irq)
+ if ((status & de->vsync_irq) && malidp->crtc.enabled)
drm_crtc_handle_vblank(&malidp->crtc);
malidp_hw_clear_irq(hwdev, MALIDP_DE_BLOCK, status);