All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
To: Gustavo Padovan <gustavo@padovan.org>,
	Sean Paul <seanpaul@chromium.org>,
	Daniel Vetter <daniel@ffwll.ch>,
	Haneen Mohammed <hamohammed.sa@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Subject: [PATCH] drm/vkms: Add vblank events simulated by hrtimers
Date: Mon, 25 Jun 2018 14:19:22 -0300	[thread overview]
Message-ID: <20180625171922.5ofev566kghxxxwu@smtp.gmail.com> (raw)

This commit adds regular vblank events simulated through hrtimers, which
is a feature required by VKMS to mimic real hardware. In this sense,
this commit adopts a default frequency of 60Hz for vblank interval.
Finally, this commit implements handlers for some of the atomic and
vblank hooks.

Signed-off-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
---
Note:
	- This patch depends on the patchset "drm/vkms: Updates to meet basic
		kms_flip requirements"
		link: https://lists.freedesktop.org/archives/dri-devel/2018-June/180823.html

 drivers/gpu/drm/vkms/vkms_crtc.c | 90 +++++++++++++++++++++++++++++++-
 drivers/gpu/drm/vkms/vkms_drv.c  |  6 +++
 drivers/gpu/drm/vkms/vkms_drv.h  |  9 ++++
 3 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 84cc05506b09..73aae129c37d 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -10,6 +10,52 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 
+static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
+{
+	struct vkms_output *output = container_of(timer, struct vkms_output,
+						  vblank_hrtimer);
+	struct drm_crtc *crtc = &output->crtc;
+	unsigned long flags;
+	int ret_overrun;
+	bool ret;
+
+	ret = drm_crtc_handle_vblank(&output->crtc);
+	if (!ret)
+		DRM_ERROR("vkms failure on handling vblank");
+
+	spin_lock_irqsave(&crtc->dev->event_lock, flags);
+	if (output->event) {
+		drm_crtc_send_vblank_event(crtc, output->event);
+		drm_crtc_vblank_put(crtc);
+		output->event = NULL;
+	}
+	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+	ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
+					  output->period_ns);
+
+	return HRTIMER_RESTART;
+}
+
+static int vkms_enable_vblank(struct drm_crtc *crtc)
+{
+	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+
+	hrtimer_init(&out->vblank_hrtimer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+	out->vblank_hrtimer.function = &vkms_vblank_simulate;
+	out->period_ns = ktime_set(0, DEFAULT_VBLANK_NS);
+	hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_ABS);
+
+	return 0;
+}
+
+static void vkms_disable_vblank(struct drm_crtc *crtc)
+{
+	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+
+	hrtimer_cancel(&out->vblank_hrtimer);
+}
+
 static const struct drm_crtc_funcs vkms_crtc_funcs = {
 	.set_config             = drm_atomic_helper_set_config,
 	.destroy                = drm_crtc_cleanup,
@@ -17,6 +63,8 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
 	.reset                  = drm_atomic_helper_crtc_reset,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
+	.enable_vblank		= vkms_enable_vblank,
+	.disable_vblank		= vkms_disable_vblank,
 };
 
 static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
@@ -27,12 +75,50 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
 
 static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
 				    struct drm_crtc_state *old_state)
+{
+	drm_crtc_vblank_on(crtc);
+}
+
+static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_s)
+{
+	struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc);
+
+	if (crtc->state->event) {
+		crtc->state->event->pipe = drm_crtc_index(crtc);
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+		vkms_output->event = crtc->state->event;
+		crtc->state->event = NULL;
+	}
+}
+
+static void vkms_crtc_atomic_flush(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state)
+{
+	struct drm_pending_vblank_event *event = crtc->state->event;
+
+	if (!event)
+		return;
+
+	crtc->state->event = NULL;
+
+	spin_lock_irq(&crtc->dev->event_lock);
+	if (drm_crtc_vblank_get(crtc))
+		drm_crtc_send_vblank_event(crtc, event);
+	spin_unlock_irq(&crtc->dev->event_lock);
+}
+
+static void vkms_crtc_commit(struct drm_crtc *crtc)
 {
 }
 
 static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
-	.atomic_check  = vkms_crtc_atomic_check,
-	.atomic_enable = vkms_crtc_atomic_enable,
+	.atomic_check	= vkms_crtc_atomic_check,
+	.atomic_enable	= vkms_crtc_atomic_enable,
+	.atomic_flush	= vkms_crtc_atomic_flush,
+	.atomic_begin	= vkms_crtc_atomic_begin,
+	.commit		= vkms_crtc_commit,
 };
 
 int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index fe93f8c17997..c56d66d9ec56 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -102,6 +102,12 @@ static int __init vkms_init(void)
 		goto out_fini;
 	}
 
+	ret = drm_vblank_init(&vkms_device->drm, 1);
+	if (ret) {
+		DRM_ERROR("Failed to vblank\n");
+		goto out_fini;
+	}
+
 	ret = vkms_modeset_init(vkms_device);
 	if (ret)
 		goto out_unregister;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 76f1720f81a5..f115e7d1ae03 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -5,6 +5,7 @@
 #include <drm/drm.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_encoder.h>
+#include <linux/hrtimer.h>
 
 #define XRES_MIN    32
 #define YRES_MIN    32
@@ -15,6 +16,8 @@
 #define XRES_MAX  8192
 #define YRES_MAX  8192
 
+#define DEFAULT_VBLANK_NS 16666666
+
 static const u32 vkms_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
@@ -23,6 +26,9 @@ struct vkms_output {
 	struct drm_crtc crtc;
 	struct drm_encoder encoder;
 	struct drm_connector connector;
+	struct hrtimer vblank_hrtimer;
+	ktime_t period_ns;
+	struct drm_pending_vblank_event *event;
 };
 
 struct vkms_device {
@@ -37,6 +43,9 @@ struct vkms_gem_object {
 	struct page **pages;
 };
 
+#define drm_crtc_to_vkms_output(target) \
+	container_of(target, struct vkms_output, crtc)
+
 int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
 		   struct drm_plane *primary, struct drm_plane *cursor);
 
-- 
2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

             reply	other threads:[~2018-06-25 17:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-25 17:19 Rodrigo Siqueira [this message]
2018-06-25 17:49 ` [PATCH] drm/vkms: Add vblank events simulated by hrtimers Ville Syrjälä
2018-06-26  2:25   ` Rodrigo Siqueira
2018-06-26  7:54     ` Daniel Vetter
2018-06-26 16:58       ` Rodrigo Siqueira

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180625171922.5ofev566kghxxxwu@smtp.gmail.com \
    --to=rodrigosiqueiramelo@gmail.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gustavo@padovan.org \
    --cc=hamohammed.sa@gmail.com \
    --cc=seanpaul@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.