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>
This commit is contained in:
@ -1009,6 +1009,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_crtc_vblank_put);
|
EXPORT_SYMBOL(drm_crtc_vblank_put);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_wait_one_vblank - wait for one vblank
|
||||||
|
* @dev: DRM device
|
||||||
|
* @crtc: crtc index
|
||||||
|
*
|
||||||
|
* This waits for one vblank to pass on @crtc, using the irq driver interfaces.
|
||||||
|
* It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
|
||||||
|
* due to lack of driver support or because the crtc is off.
|
||||||
|
*/
|
||||||
|
void drm_wait_one_vblank(struct drm_device *dev, int crtc)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u32 last;
|
||||||
|
|
||||||
|
ret = drm_vblank_get(dev, crtc);
|
||||||
|
if (WARN_ON(ret))
|
||||||
|
return;
|
||||||
|
|
||||||
|
last = drm_vblank_count(dev, crtc);
|
||||||
|
|
||||||
|
ret = wait_event_timeout(dev->vblank[crtc].queue,
|
||||||
|
last != drm_vblank_count(dev, crtc),
|
||||||
|
msecs_to_jiffies(100));
|
||||||
|
|
||||||
|
WARN_ON(ret == 0);
|
||||||
|
|
||||||
|
drm_vblank_put(dev, crtc);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_wait_one_vblank);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_crtc_wait_one_vblank - wait for one vblank
|
||||||
|
* @crtc: DRM crtc
|
||||||
|
*
|
||||||
|
* This waits for one vblank to pass on @crtc, using the irq driver interfaces.
|
||||||
|
* It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
|
||||||
|
* due to lack of driver support or because the crtc is off.
|
||||||
|
*/
|
||||||
|
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_vblank_off - disable vblank events on a CRTC
|
* drm_vblank_off - disable vblank events on a CRTC
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
|
@ -1327,6 +1327,8 @@ extern int drm_vblank_get(struct drm_device *dev, int crtc);
|
|||||||
extern void drm_vblank_put(struct drm_device *dev, int crtc);
|
extern void drm_vblank_put(struct drm_device *dev, int crtc);
|
||||||
extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
|
extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
|
||||||
extern void drm_crtc_vblank_put(struct drm_crtc *crtc);
|
extern void drm_crtc_vblank_put(struct drm_crtc *crtc);
|
||||||
|
extern void drm_wait_one_vblank(struct drm_device *dev, int crtc);
|
||||||
|
extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
|
||||||
extern void drm_vblank_off(struct drm_device *dev, int crtc);
|
extern void drm_vblank_off(struct drm_device *dev, int crtc);
|
||||||
extern void drm_vblank_on(struct drm_device *dev, int crtc);
|
extern void drm_vblank_on(struct drm_device *dev, int crtc);
|
||||||
extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
|
extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
|
||||||
|
Reference in New Issue
Block a user