diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-25 17:34:03 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-08-11 08:25:21 -0400 |
commit | e8450f51a4b39cfe0878b4aee339820b2bfff240 (patch) | |
tree | ee6cf4685f8524bf47cf49911d61ba21c77a5b33 /drivers/gpu/drm/drm_irq.c | |
parent | 2a0d7cfd9482ca4c10a4d8794791760a6a7ce40c (diff) |
drm/irq: Implement a generic vblank_wait function
As usual in both a crtc index and a struct drm_crtc * version.
The function assumes that no one drivers their display below 10Hz, and
it will complain if the vblank wait takes longer than that.
v2: Also check dev->max_vblank_counter since some drivers register a
fake get_vblank_counter function.
v3: Use drm_vblank_count instead of calling the low-level
->get_vblank_counter callback. That way we'll get the sw-cooked
counter for platforms without proper vblank support and so can ditch
the max_vblank_counter check again.
v4: Review from Michel Dänzer:
- Restore lost notes about v3:
- Spelling in kerneldoc.
- Inline wait_event condition.
- s/vblank_wait/wait_one_vblank/
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6f16a104d6d0..e64d24951fc2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -1010,6 +1010,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc) | |||
1010 | EXPORT_SYMBOL(drm_crtc_vblank_put); | 1010 | EXPORT_SYMBOL(drm_crtc_vblank_put); |
1011 | 1011 | ||
1012 | /** | 1012 | /** |
1013 | * drm_wait_one_vblank - wait for one vblank | ||
1014 | * @dev: DRM device | ||
1015 | * @crtc: crtc index | ||
1016 | * | ||
1017 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces. | ||
1018 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. | ||
1019 | * due to lack of driver support or because the crtc is off. | ||
1020 | */ | ||
1021 | void drm_wait_one_vblank(struct drm_device *dev, int crtc) | ||
1022 | { | ||
1023 | int ret; | ||
1024 | u32 last; | ||
1025 | |||
1026 | ret = drm_vblank_get(dev, crtc); | ||
1027 | if (WARN_ON(ret)) | ||
1028 | return; | ||
1029 | |||
1030 | last = drm_vblank_count(dev, crtc); | ||
1031 | |||
1032 | ret = wait_event_timeout(dev->vblank[crtc].queue, | ||
1033 | last != drm_vblank_count(dev, crtc), | ||
1034 | msecs_to_jiffies(100)); | ||
1035 | |||
1036 | WARN_ON(ret == 0); | ||
1037 | |||
1038 | drm_vblank_put(dev, crtc); | ||
1039 | } | ||
1040 | EXPORT_SYMBOL(drm_wait_one_vblank); | ||
1041 | |||
1042 | /** | ||
1043 | * drm_crtc_wait_one_vblank - wait for one vblank | ||
1044 | * @crtc: DRM crtc | ||
1045 | * | ||
1046 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces. | ||
1047 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. | ||
1048 | * due to lack of driver support or because the crtc is off. | ||
1049 | */ | ||
1050 | void drm_crtc_wait_one_vblank(struct drm_crtc *crtc) | ||
1051 | { | ||
1052 | drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc)); | ||
1053 | } | ||
1054 | EXPORT_SYMBOL(drm_crtc_wait_one_vblank); | ||
1055 | |||
1056 | /** | ||
1013 | * drm_vblank_off - disable vblank events on a CRTC | 1057 | * drm_vblank_off - disable vblank events on a CRTC |
1014 | * @dev: DRM device | 1058 | * @dev: DRM device |
1015 | * @crtc: CRTC in question | 1059 | * @crtc: CRTC in question |