[PATCH 12/12] [RFC] drm/crtc-helper: Enforce sane vblank counter semantics

Daniel Vetter daniel.vetter at ffwll.ch
Wed May 14 11:51:17 PDT 2014


It literally took us years in i915 to track down all the vblank
bogosity, which means that userspace has now code to deal with random
crap like stuck vblank waits, needless counter wraps and other
hilarity.

To make sure that all drivers are at least somewhat sane enforce
minimal standards in the crtc helpers. Note that this is not perfect
since for intermediate levels it's unclear whether the vblank will
keep on running. Modern userspace is advised to just never use those.

Totatlly untested.

Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 drivers/gpu/drm/drm_crtc_helper.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index df281b54db01..64d8797cd172 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -167,6 +167,8 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
 			else
 				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
 			crtc->primary->fb = NULL;
+
+			drm_crtc_vblank_off(crtc->dev, crtc);
 		}
 	}
 }
@@ -323,6 +325,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 
 	crtc_funcs->prepare(crtc);
 
+	drm_crtc_vblank_off(dev, crtc);
+
 	/* Set up the DPLL and any encoders state that needs to adjust or depend
 	 * on the DPLL.
 	 */
@@ -349,6 +353,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
 	crtc_funcs->commit(crtc);
 
+	drm_crtc_vblank_on(dev, crtc);
+
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 
 		if (encoder->crtc != crtc)
@@ -767,6 +773,9 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
 			if (crtc_funcs->dpms)
 				(*crtc_funcs->dpms) (crtc,
 						     drm_helper_choose_crtc_dpms(crtc));
+
+			if (mode == DRM_MODE_DPMS_ON)
+				drm_crtc_vblank_on(crtc->dev, crtc);
 		}
 		if (encoder)
 			drm_helper_encoder_dpms(encoder, encoder_dpms);
@@ -781,6 +790,9 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
 			if (crtc_funcs->dpms)
 				(*crtc_funcs->dpms) (crtc,
 						     drm_helper_choose_crtc_dpms(crtc));
+
+			if (mode == DRM_MODE_DPMS_OFF)
+				drm_crtc_vblank_off(crtc->dev, crtc);
 		}
 	}
 
-- 
1.8.3.1



More information about the dri-devel mailing list