瀏覽代碼

drm: Add dev->vblank_disable_immediate flag

Add a flag to drm_device which will cause the vblank code to bypass the
disable timer and always disable the vblank interrupt immediately when
the last reference is dropped.

v2: Add some notes about the flag to the kernel doc

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Ville Syrjälä 11 年之前
父節點
當前提交
00185e6670
共有 3 個文件被更改,包括 17 次插入1 次删除
  1. 6 0
      Documentation/DocBook/drm.tmpl
  2. 1 1
      drivers/gpu/drm/drm_irq.c
  3. 10 0
      include/drm/drmP.h

+ 6 - 0
Documentation/DocBook/drm.tmpl

@@ -3387,6 +3387,12 @@ void (*disable_vblank) (struct drm_device *dev, int crtc);</synopsis>
       module parameter or the <varname>drm_vblank_offdelay</varname> global
       module parameter or the <varname>drm_vblank_offdelay</varname> global
       variable and expressed in milliseconds. Its default value is 5000 ms.
       variable and expressed in milliseconds. Its default value is 5000 ms.
       Zero means never disable, and a negative value means disable immediately.
       Zero means never disable, and a negative value means disable immediately.
+      Drivers may override the behaviour by setting the
+      <structname>drm_device</structname>
+      <structfield>vblank_disable_immediate</structfield> flag, which when set
+      causes vblank interrupts to be disabled immediately regardless of the
+      drm_vblank_offdelay value. The flag should only be set if there's a
+      properly working hardware vblank counter present.
     </para>
     </para>
     <para>
     <para>
       When a vertical blanking interrupt occurs drivers only need to call the
       When a vertical blanking interrupt occurs drivers only need to call the

+ 1 - 1
drivers/gpu/drm/drm_irq.c

@@ -994,7 +994,7 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
 
 
 	/* Last user schedules interrupt disable */
 	/* Last user schedules interrupt disable */
 	if (atomic_dec_and_test(&vblank->refcount)) {
 	if (atomic_dec_and_test(&vblank->refcount)) {
-		if (drm_vblank_offdelay < 0)
+		if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
 			vblank_disable_fn((unsigned long)vblank);
 			vblank_disable_fn((unsigned long)vblank);
 		else if (drm_vblank_offdelay > 0)
 		else if (drm_vblank_offdelay > 0)
 			mod_timer(&vblank->disable_timer,
 			mod_timer(&vblank->disable_timer,

+ 10 - 0
include/drm/drmP.h

@@ -1074,6 +1074,16 @@ struct drm_device {
 	 */
 	 */
 	bool vblank_disable_allowed;
 	bool vblank_disable_allowed;
 
 
+	/*
+	 * If true, vblank interrupt will be disabled immediately when the
+	 * refcount drops to zero, as opposed to via the vblank disable
+	 * timer.
+	 * This can be set to true it the hardware has a working vblank
+	 * counter and the driver uses drm_vblank_on() and drm_vblank_off()
+	 * appropriately.
+	 */
+	bool vblank_disable_immediate;
+
 	/* array of size num_crtcs */
 	/* array of size num_crtcs */
 	struct drm_vblank_crtc *vblank;
 	struct drm_vblank_crtc *vblank;