drm/vblank: Data type fixes for 64-bit vblank sequences.
drm_vblank_count() has an u32 type returning what is a 64-bit vblank count.
The effect of this is when drm_wait_vblank_ioctl() tries to widen the user
space requested vblank sequence using this clipped 32-bit count(when the
value is >= 2^32) as reference, the requested sequence remains a 32-bit
value and gets queued like that. However, the code that checks if the
requested sequence has passed compares this against the 64-bit vblank
count.
With drm_vblank_count() returning all bits of the vblank count, update
drm_crtc_accurate_vblank_count() so that drm_crtc_arm_vblank_event() queues
the correct sequence. Otherwise, this leads to prolonged waits for a vblank
sequence when the current count is >=2^32.
Finally, fix drm_wait_one_vblank() too.
v2: Commit message fix (Keith)
Squash commits (Rodrigo)
Fixes: 570e86963a
("drm: Widen vblank count to 64-bits [v3]")
Cc: Keith Packard <keithp@keithp.com>
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180203051302.9974-1-dhinakaran.pandiyan@intel.com
This commit is contained in:
Родитель
6e8c06d291
Коммит
3b765c0b76
|
@ -271,7 +271,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
|
||||||
store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
|
store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
|
static u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
|
||||||
{
|
{
|
||||||
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
||||||
|
|
||||||
|
@ -292,11 +292,11 @@ static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
|
||||||
* This is mostly useful for hardware that can obtain the scanout position, but
|
* This is mostly useful for hardware that can obtain the scanout position, but
|
||||||
* doesn't have a hardware frame counter.
|
* doesn't have a hardware frame counter.
|
||||||
*/
|
*/
|
||||||
u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
|
u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
unsigned int pipe = drm_crtc_index(crtc);
|
unsigned int pipe = drm_crtc_index(crtc);
|
||||||
u32 vblank;
|
u64 vblank;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
WARN_ONCE(drm_debug & DRM_UT_VBL && !dev->driver->get_vblank_timestamp,
|
WARN_ONCE(drm_debug & DRM_UT_VBL && !dev->driver->get_vblank_timestamp,
|
||||||
|
@ -1055,7 +1055,7 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
|
||||||
{
|
{
|
||||||
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
||||||
int ret;
|
int ret;
|
||||||
u32 last;
|
u64 last;
|
||||||
|
|
||||||
if (WARN_ON(pipe >= dev->num_crtcs))
|
if (WARN_ON(pipe >= dev->num_crtcs))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -179,7 +179,7 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
|
||||||
void drm_crtc_vblank_off(struct drm_crtc *crtc);
|
void drm_crtc_vblank_off(struct drm_crtc *crtc);
|
||||||
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
|
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
|
||||||
void drm_crtc_vblank_on(struct drm_crtc *crtc);
|
void drm_crtc_vblank_on(struct drm_crtc *crtc);
|
||||||
u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
|
u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
|
||||||
|
|
||||||
bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
|
bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
|
||||||
unsigned int pipe, int *max_error,
|
unsigned int pipe, int *max_error,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче