diff options
author | Dave Airlie <airlied@redhat.com> | 2016-10-10 16:36:16 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-10-10 16:36:16 +1000 |
commit | 9c704d14386dc1deeb695f2a180f9a00f23fa650 (patch) | |
tree | fd4b11b8119a0d8fca8a3ccf45e76e2334b86b8e /drivers/gpu/drm/drm_irq.c | |
parent | a74feb65a451105bb9aba6ea695b7068b0690046 (diff) | |
parent | 0546d685f07cc4fc5748fd36e57d167877c2842d (diff) |
Merge tag 'topic/drm-misc-2016-10-05' of git://anongit.freedesktop.org/drm-intel into drm-next
Another attempt, this time rebased and without the pipe crc patches:
- display_info cleanups from Ville
- make prime/gem lookups faster with rbtrees (Chris)
- misc stuff all over
* tag 'topic/drm-misc-2016-10-05' of git://anongit.freedesktop.org/drm-intel:
drm/rockchip: analogix_dp: Refuse to enable PSR if panel doesn't support it
drm/bridge: analogix_dp: Add analogix_dp_psr_supported
drm/fb-helper: add DRM_FB_HELPER_DEFAULT_OPS for fb_ops
drm: Document caveats around atomic event handling
uapi: add missing install of sync_file.h
drm: Simplify drm_printk to reduce object size quite a bit
drm/i915: Account for sink max TMDS clock when checking the port clock
drm/i915: Replace a bunch of connector->base.display_info with a local variable
drm/edid: Move dvi_dual/max_tmds_clock parsing out from drm_edid_to_eld()
drm/edid: Clear the old cea_rev when there's no CEA extension in the new EDID
drm/edid: Reduce the number of times we parse the CEA extension block
drm/edid: Don't pass around drm_display_info needlessly
drm/edid: Move dvi_dual/max_tmds_clock to drm_display_info
drm/edid: Make max_tmds_clock kHz instead of MHz
drm/edid: Clear old dvi_dual/max_tmds_clock before parsing the new EDID
drm/edid: Clear old audio latency values before parsing the new EDID
drm: Convert prime dma-buf <-> handle to rbtree
drm/mediatek: mark symbols static where possible
drm/rockchip: mark symbols static where possible
drm/rockchip: add missing header dependencies
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 404a1ce7730c..b969a64a1514 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1008,6 +1008,31 @@ static void send_vblank_event(struct drm_device *dev, * period. This helper function implements exactly the required vblank arming * behaviour. * + * NOTE: Drivers using this to send out the event in struct &drm_crtc_state + * as part of an atomic commit must ensure that the next vblank happens at + * exactly the same time as the atomic commit is committed to the hardware. This + * function itself does **not** protect again the next vblank interrupt racing + * with either this function call or the atomic commit operation. A possible + * sequence could be: + * + * 1. Driver commits new hardware state into vblank-synchronized registers. + * 2. A vblank happens, committing the hardware state. Also the corresponding + * vblank interrupt is fired off and fully processed by the interrupt + * handler. + * 3. The atomic commit operation proceeds to call drm_crtc_arm_vblank_event(). + * 4. The event is only send out for the next vblank, which is wrong. + * + * An equivalent race can happen when the driver calls + * drm_crtc_arm_vblank_event() before writing out the new hardware state. + * + * The only way to make this work safely is to prevent the vblank from firing + * (and the hardware from committing anything else) until the entire atomic + * commit sequence has run to completion. If the hardware does not have such a + * feature (e.g. using a "go" bit), then it is unsafe to use this functions. + * Instead drivers need to manually send out the event from their interrupt + * handler by calling drm_crtc_send_vblank_event() and make sure that there's no + * possible race with the hardware committing the atomic update. + * * Caller must hold event lock. Caller must also hold a vblank reference for * the event @e, which will be dropped when the next vblank arrives. */ @@ -1030,8 +1055,11 @@ EXPORT_SYMBOL(drm_crtc_arm_vblank_event); * @crtc: the source CRTC of the vblank event * @e: the event to send * - * Updates sequence # and timestamp on event, and sends it to userspace. - * Caller must hold event lock. + * Updates sequence # and timestamp on event for the most recently processed + * vblank, and sends it to userspace. Caller must hold event lock. + * + * See drm_crtc_arm_vblank_event() for a helper which can be used in certain + * situation, especially to send out events for atomic commit operations. */ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e) |