drm: Add DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags v2
These flags allow userspace to explicitly specify the target vertical blank period when a flip should take effect. v2: * Add new struct drm_mode_crtc_page_flip_target instead of modifying struct drm_mode_crtc_page_flip, to make sure all existing userspace code keeps compiling (Daniel Vetter) Acked-by: Christian König <christian.koenig@amd.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:

committed by
Alex Deucher

parent
5dd20bbae8
commit
f837297ad8
@@ -5398,15 +5398,23 @@ out:
|
||||
int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_mode_crtc_page_flip *page_flip = data;
|
||||
struct drm_mode_crtc_page_flip_target *page_flip = data;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_framebuffer *fb = NULL;
|
||||
struct drm_pending_vblank_event *e = NULL;
|
||||
u32 target_vblank = 0;
|
||||
u32 target_vblank = page_flip->sequence;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
|
||||
page_flip->reserved != 0)
|
||||
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS)
|
||||
return -EINVAL;
|
||||
|
||||
if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET))
|
||||
return -EINVAL;
|
||||
|
||||
/* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags
|
||||
* can be specified
|
||||
*/
|
||||
if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET)
|
||||
return -EINVAL;
|
||||
|
||||
if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
|
||||
@@ -5417,15 +5425,41 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
||||
return -ENOENT;
|
||||
|
||||
if (crtc->funcs->page_flip_target) {
|
||||
u32 current_vblank;
|
||||
int r;
|
||||
|
||||
r = drm_crtc_vblank_get(crtc);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
target_vblank = drm_crtc_vblank_count(crtc) +
|
||||
!(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC);
|
||||
} else if (crtc->funcs->page_flip == NULL) {
|
||||
current_vblank = drm_crtc_vblank_count(crtc);
|
||||
|
||||
switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
|
||||
case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
|
||||
if ((int)(target_vblank - current_vblank) > 1) {
|
||||
DRM_DEBUG("Invalid absolute flip target %u, "
|
||||
"must be <= %u\n", target_vblank,
|
||||
current_vblank + 1);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE:
|
||||
if (target_vblank != 0 && target_vblank != 1) {
|
||||
DRM_DEBUG("Invalid relative flip target %u, "
|
||||
"must be 0 or 1\n", target_vblank);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
target_vblank += current_vblank;
|
||||
break;
|
||||
default:
|
||||
target_vblank = current_vblank +
|
||||
!(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC);
|
||||
break;
|
||||
}
|
||||
} else if (crtc->funcs->page_flip == NULL ||
|
||||
(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user