Skip to content

Commit

Permalink
drm/vc4: Resolve the vblank warnings on mode switching
Browse files Browse the repository at this point in the history
The details over when and how a driver is to service the
vblank events are sketchy, and the fkms driver was triggering
a kernel warning every time the crtc was enabled or disabled.

Copy the event handling as used by the vc4-kms driver slightly
more closely, and we avoid the warnings.

#3020

Signed-off-by: Dave Stevenson <[email protected]>
  • Loading branch information
6by9 authored and popcornmix committed Sep 1, 2020
1 parent eb2a292 commit 65ca93b
Showing 1 changed file with 33 additions and 15 deletions.
48 changes: 33 additions & 15 deletions drivers/gpu/drm/vc4/vc4_firmware_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)

static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct drm_plane *plane;

DRM_DEBUG_KMS("[CRTC:%d] vblanks off.\n",
Expand All @@ -962,6 +963,35 @@ static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_s

drm_atomic_crtc_for_each_plane(plane, crtc)
vc4_plane_atomic_disable(plane, plane->state);

/*
* Make sure we issue a vblank event after disabling the CRTC if
* someone was waiting it.
*/
if (crtc->state->event) {
unsigned long flags;

spin_lock_irqsave(&dev->event_lock, flags);
drm_crtc_send_vblank_event(crtc, crtc->state->event);
crtc->state->event = NULL;
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}

static void vc4_crtc_consume_event(struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_device *dev = crtc->dev;
unsigned long flags;

crtc->state->event->pipe = drm_crtc_index(crtc);

WARN_ON(drm_crtc_vblank_get(crtc) != 0);

spin_lock_irqsave(&dev->event_lock, flags);
vc4_crtc->event = crtc->state->event;
crtc->state->event = NULL;
spin_unlock_irqrestore(&dev->event_lock, flags);
}

static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
Expand All @@ -971,6 +1001,7 @@ static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_st
DRM_DEBUG_KMS("[CRTC:%d] vblanks on.\n",
crtc->base.id);
drm_crtc_vblank_on(crtc);
vc4_crtc_consume_event(crtc);

/* Unblank the planes (if they're supposed to be displayed). */
drm_atomic_crtc_for_each_plane(plane, crtc)
Expand Down Expand Up @@ -1042,23 +1073,10 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_device *dev = crtc->dev;

DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n",
crtc->base.id);
if (crtc->state->event) {
unsigned long flags;

crtc->state->event->pipe = drm_crtc_index(crtc);

WARN_ON(drm_crtc_vblank_get(crtc) != 0);

spin_lock_irqsave(&dev->event_lock, flags);
vc4_crtc->event = crtc->state->event;
crtc->state->event = NULL;
spin_unlock_irqrestore(&dev->event_lock, flags);
}
if (crtc->state->active && old_state->active && crtc->state->event)
vc4_crtc_consume_event(crtc);
}

static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
Expand Down

0 comments on commit 65ca93b

Please sign in to comment.