AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/vblank: allow dynamic per-crtc vblank off delay
@ 2024-07-08 20:29 Hamza Mahfooz
  2024-07-08 20:29 ` [PATCH 2/2] drm/amd/display: use drm_crtc_set_vblank_offdelay() Hamza Mahfooz
  2024-07-09  9:30 ` [PATCH 1/2] drm/vblank: allow dynamic per-crtc vblank off delay Daniel Vetter
  0 siblings, 2 replies; 9+ messages in thread
From: Hamza Mahfooz @ 2024-07-08 20:29 UTC (permalink / raw)
  To: dri-devel
  Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
	Christian König, Maxime Ripard, Thomas Zimmermann, Alex Hung,
	Wayne Lin, Mario Limonciello, amd-gfx, Hamza Mahfooz

We would like to be able to adjust the vblank off delay dynamically for
a given CRTC. Since, it will allow drivers to apply static screen
optimizations more quickly and consequently allow users to benefit more
so from the power savings afforded by the aforementioned optimizations.

Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
---
 drivers/gpu/drm/drm_vblank.c | 31 ++++++++++++++++++++++++++-----
 include/drm/drm_vblank.h     |  7 +++++++
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 702a12bc93bd..4f475131a092 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -529,6 +529,7 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
 
 		vblank->dev = dev;
 		vblank->pipe = i;
+		vblank->offdelay_ms = drm_vblank_offdelay;
 		init_waitqueue_head(&vblank->queue);
 		timer_setup(&vblank->disable_timer, vblank_disable_fn, 0);
 		seqlock_init(&vblank->seqlock);
@@ -1229,6 +1230,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_get);
 void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
 {
 	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+	int vblank_offdelay = vblank->offdelay_ms;
 
 	if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
 		return;
@@ -1238,13 +1240,13 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
 
 	/* Last user schedules interrupt disable */
 	if (atomic_dec_and_test(&vblank->refcount)) {
-		if (drm_vblank_offdelay == 0)
+		if (!vblank_offdelay)
 			return;
-		else if (drm_vblank_offdelay < 0)
+		else if (vblank_offdelay < 0)
 			vblank_disable_fn(&vblank->disable_timer);
 		else if (!dev->vblank_disable_immediate)
 			mod_timer(&vblank->disable_timer,
-				  jiffies + ((drm_vblank_offdelay * HZ)/1000));
+				  jiffies + ((vblank_offdelay * HZ) / 1000));
 	}
 }
 
@@ -1455,6 +1457,25 @@ void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
 }
 EXPORT_SYMBOL(drm_crtc_set_max_vblank_count);
 
+/**
+ * drm_crtc_set_vblank_offdelay - configure the vblank off delay value
+ * @crtc: CRTC in question
+ * @offdelay: off delay value
+ *
+ * If used, must be called before drm_vblank_on().
+ */
+void drm_crtc_set_vblank_offdelay(struct drm_crtc *crtc, int offdelay)
+{
+	struct drm_device *dev = crtc->dev;
+	unsigned int pipe = drm_crtc_index(crtc);
+	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+
+	drm_WARN_ON(dev, dev->vblank_disable_immediate);
+
+	vblank->offdelay_ms = offdelay;
+}
+EXPORT_SYMBOL(drm_crtc_set_vblank_offdelay);
+
 /**
  * drm_crtc_vblank_on - enable vblank events on a CRTC
  * @crtc: CRTC in question
@@ -1490,7 +1511,7 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 	 * re-enable interrupts if there are users left, or the
 	 * user wishes vblank interrupts to be enabled all the time.
 	 */
-	if (atomic_read(&vblank->refcount) != 0 || drm_vblank_offdelay == 0)
+	if (atomic_read(&vblank->refcount) != 0 || !vblank->offdelay_ms)
 		drm_WARN_ON(dev, drm_vblank_enable(dev, pipe));
 	spin_unlock_irq(&dev->vbl_lock);
 }
@@ -1909,7 +1930,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
 	 * drm_handle_vblank_events) so that the timestamp is always accurate.
 	 */
 	disable_irq = (dev->vblank_disable_immediate &&
-		       drm_vblank_offdelay > 0 &&
+		       vblank->offdelay_ms > 0 &&
 		       !atomic_read(&vblank->refcount));
 
 	drm_handle_vblank_events(dev, pipe);
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 7f3957943dd1..f92f28b816af 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -187,6 +187,12 @@ struct drm_vblank_crtc {
 	 */
 	int linedur_ns;
 
+	/**
+	 * @offdelay_ms: Vblank off delay in ms, used to determine how long
+	 * @disable_timer waits before disabling.
+	 */
+	int offdelay_ms;
+
 	/**
 	 * @hwmode:
 	 *
@@ -255,6 +261,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
 wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc);
 void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
 				   u32 max_vblank_count);
+void drm_crtc_set_vblank_offdelay(struct drm_crtc *crtc, int offdelay);
 
 /*
  * Helpers for struct drm_crtc_funcs
-- 
2.45.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-07-15  8:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-08 20:29 [PATCH 1/2] drm/vblank: allow dynamic per-crtc vblank off delay Hamza Mahfooz
2024-07-08 20:29 ` [PATCH 2/2] drm/amd/display: use drm_crtc_set_vblank_offdelay() Hamza Mahfooz
2024-07-09  9:32   ` Daniel Vetter
2024-07-09 10:09     ` Daniel Vetter
2024-07-09 14:02       ` Hamza Mahfooz
2024-07-10  8:43         ` Daniel Vetter
2024-07-10 21:13           ` Hamza Mahfooz
2024-07-15  8:40             ` Daniel Vetter
2024-07-09  9:30 ` [PATCH 1/2] drm/vblank: allow dynamic per-crtc vblank off delay Daniel Vetter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox