Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f3bbe07 authored by Maxime Ripard's avatar Maxime Ripard Committed by Daniel Vetter
Browse files

drm/fb-helper: implement ioctl FBIO_WAITFORVSYNC



Implement legacy framebuffer ioctl FBIO_WAITFORVSYNC in the generic
framebuffer emulation driver. Legacy framebuffer users like non kms/drm
based OpenGL(ES)/EGL implementations may require the ioctl to
synchronize drawing or buffer flip for double buffering. It is tested on
the i.MX6.

Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 35f5022f
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -1244,6 +1244,74 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_setcmap);

/**
 * drm_fb_helper_ioctl - legacy ioctl implementation
 * @info: fbdev registered by the helper
 * @cmd: ioctl command
 * @arg: ioctl argument
 *
 * A helper to implement the standard fbdev ioctl. Only
 * FBIO_WAITFORVSYNC is implemented for now.
 */
int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
			unsigned long arg)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct drm_device *dev = fb_helper->dev;
	struct drm_mode_set *mode_set;
	struct drm_crtc *crtc;
	int ret = 0;

	mutex_lock(&dev->mode_config.mutex);
	if (!drm_fb_helper_is_bound(fb_helper)) {
		ret = -EBUSY;
		goto unlock;
	}

	switch (cmd) {
	case FBIO_WAITFORVSYNC:
		/*
		 * Only consider the first CRTC.
		 *
		 * This ioctl is supposed to take the CRTC number as
		 * an argument, but in fbdev times, what that number
		 * was supposed to be was quite unclear, different
		 * drivers were passing that argument differently
		 * (some by reference, some by value), and most of the
		 * userspace applications were just hardcoding 0 as an
		 * argument.
		 *
		 * The first CRTC should be the integrated panel on
		 * most drivers, so this is the best choice we can
		 * make. If we're not smart enough here, one should
		 * just consider switch the userspace to KMS.
		 */
		mode_set = &fb_helper->crtc_info[0].mode_set;
		crtc = mode_set->crtc;

		/*
		 * Only wait for a vblank event if the CRTC is
		 * enabled, otherwise just don't do anythintg,
		 * not even report an error.
		 */
		ret = drm_crtc_vblank_get(crtc);
		if (!ret) {
			drm_crtc_wait_one_vblank(crtc);
			drm_crtc_vblank_put(crtc);
		}

		ret = 0;
		goto unlock;
	default:
		ret = -ENOTTY;
	}

unlock:
	mutex_unlock(&dev->mode_config.mutex);
	return ret;
}
EXPORT_SYMBOL(drm_fb_helper_ioctl);

/**
 * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var
 * @var: screeninfo to check
+11 −1
Original line number Diff line number Diff line
@@ -230,7 +230,8 @@ struct drm_fb_helper {
	.fb_blank	= drm_fb_helper_blank, \
	.fb_pan_display	= drm_fb_helper_pan_display, \
	.fb_debug_enter = drm_fb_helper_debug_enter, \
	.fb_debug_leave = drm_fb_helper_debug_leave
	.fb_debug_leave = drm_fb_helper_debug_leave, \
	.fb_ioctl	= drm_fb_helper_ioctl

#ifdef CONFIG_DRM_FBDEV_EMULATION
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
@@ -284,6 +285,9 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,

int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);

int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
			unsigned long arg);

int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
@@ -371,6 +375,12 @@ static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
	return 0;
}

static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
				      unsigned long arg)
{
	return 0;
}

static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
{
}