xref: /linux/drivers/gpu/drm/drm_vblank_helper.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
174afeb81SThomas Zimmermann // SPDX-License-Identifier: MIT
274afeb81SThomas Zimmermann 
3*d54dbb59SThomas Zimmermann #include <drm/drm_atomic.h>
474afeb81SThomas Zimmermann #include <drm/drm_crtc.h>
574afeb81SThomas Zimmermann #include <drm/drm_managed.h>
674afeb81SThomas Zimmermann #include <drm/drm_modeset_helper_vtables.h>
774afeb81SThomas Zimmermann #include <drm/drm_print.h>
874afeb81SThomas Zimmermann #include <drm/drm_vblank.h>
974afeb81SThomas Zimmermann #include <drm/drm_vblank_helper.h>
1074afeb81SThomas Zimmermann 
1174afeb81SThomas Zimmermann /**
1274afeb81SThomas Zimmermann  * DOC: overview
1374afeb81SThomas Zimmermann  *
1474afeb81SThomas Zimmermann  * The vblank helper library provides functions for supporting vertical
1574afeb81SThomas Zimmermann  * blanking in DRM drivers.
1674afeb81SThomas Zimmermann  *
1774afeb81SThomas Zimmermann  * For vblank timers, several callback implementations are available.
1874afeb81SThomas Zimmermann  * Drivers enable support for vblank timers by setting the vblank callbacks
1974afeb81SThomas Zimmermann  * in struct &drm_crtc_funcs to the helpers provided by this library. The
2074afeb81SThomas Zimmermann  * initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
21*d54dbb59SThomas Zimmermann  * The driver further has to send the VBLANK event from its atomic_flush
22*d54dbb59SThomas Zimmermann  * callback and control vblank from the CRTC's atomic_enable and atomic_disable
23*d54dbb59SThomas Zimmermann  * callbacks. The callbacks are located in struct &drm_crtc_helper_funcs.
24*d54dbb59SThomas Zimmermann  * The vblank helper library provides implementations of these callbacks
25*d54dbb59SThomas Zimmermann  * for drivers without further requirements. The initializer macro
26*d54dbb59SThomas Zimmermann  * DRM_CRTC_HELPER_VBLANK_FUNCS sets them coveniently.
2774afeb81SThomas Zimmermann  *
2874afeb81SThomas Zimmermann  * Once the driver enables vblank support with drm_vblank_init(), each
2974afeb81SThomas Zimmermann  * CRTC's vblank timer fires according to the programmed display mode. By
3074afeb81SThomas Zimmermann  * default, the vblank timer invokes drm_crtc_handle_vblank(). Drivers with
3174afeb81SThomas Zimmermann  * more specific requirements can set their own handler function in
3274afeb81SThomas Zimmermann  * struct &drm_crtc_helper_funcs.handle_vblank_timeout.
3374afeb81SThomas Zimmermann  */
3474afeb81SThomas Zimmermann 
3574afeb81SThomas Zimmermann /*
36*d54dbb59SThomas Zimmermann  * VBLANK helpers
37*d54dbb59SThomas Zimmermann  */
38*d54dbb59SThomas Zimmermann 
39*d54dbb59SThomas Zimmermann /**
40*d54dbb59SThomas Zimmermann  * drm_crtc_vblank_atomic_flush -
41*d54dbb59SThomas Zimmermann  *	Implements struct &drm_crtc_helper_funcs.atomic_flush
42*d54dbb59SThomas Zimmermann  * @crtc: The CRTC
43*d54dbb59SThomas Zimmermann  * @state: The atomic state to apply
44*d54dbb59SThomas Zimmermann  *
45*d54dbb59SThomas Zimmermann  * The helper drm_crtc_vblank_atomic_flush() implements atomic_flush of
46*d54dbb59SThomas Zimmermann  * struct drm_crtc_helper_funcs for CRTCs that only need to send out a
47*d54dbb59SThomas Zimmermann  * VBLANK event.
48*d54dbb59SThomas Zimmermann  *
49*d54dbb59SThomas Zimmermann  * See also struct &drm_crtc_helper_funcs.atomic_flush.
50*d54dbb59SThomas Zimmermann  */
51*d54dbb59SThomas Zimmermann void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
52*d54dbb59SThomas Zimmermann 				  struct drm_atomic_state *state)
53*d54dbb59SThomas Zimmermann {
54*d54dbb59SThomas Zimmermann 	struct drm_device *dev = crtc->dev;
55*d54dbb59SThomas Zimmermann 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
56*d54dbb59SThomas Zimmermann 	struct drm_pending_vblank_event *event;
57*d54dbb59SThomas Zimmermann 
58*d54dbb59SThomas Zimmermann 	spin_lock_irq(&dev->event_lock);
59*d54dbb59SThomas Zimmermann 
60*d54dbb59SThomas Zimmermann 	event = crtc_state->event;
61*d54dbb59SThomas Zimmermann 	crtc_state->event = NULL;
62*d54dbb59SThomas Zimmermann 
63*d54dbb59SThomas Zimmermann 	if (event) {
64*d54dbb59SThomas Zimmermann 		if (drm_crtc_vblank_get(crtc) == 0)
65*d54dbb59SThomas Zimmermann 			drm_crtc_arm_vblank_event(crtc, event);
66*d54dbb59SThomas Zimmermann 		else
67*d54dbb59SThomas Zimmermann 			drm_crtc_send_vblank_event(crtc, event);
68*d54dbb59SThomas Zimmermann 	}
69*d54dbb59SThomas Zimmermann 
70*d54dbb59SThomas Zimmermann 	spin_unlock_irq(&dev->event_lock);
71*d54dbb59SThomas Zimmermann }
72*d54dbb59SThomas Zimmermann EXPORT_SYMBOL(drm_crtc_vblank_atomic_flush);
73*d54dbb59SThomas Zimmermann 
74*d54dbb59SThomas Zimmermann /**
75*d54dbb59SThomas Zimmermann  * drm_crtc_vblank_atomic_enable - Implements struct &drm_crtc_helper_funcs.atomic_enable
76*d54dbb59SThomas Zimmermann  * @crtc: The CRTC
77*d54dbb59SThomas Zimmermann  * @state: The atomic state
78*d54dbb59SThomas Zimmermann  *
79*d54dbb59SThomas Zimmermann  * The helper drm_crtc_vblank_atomic_enable() implements atomic_enable
80*d54dbb59SThomas Zimmermann  * of struct drm_crtc_helper_funcs for CRTCs the only need to enable VBLANKs.
81*d54dbb59SThomas Zimmermann  *
82*d54dbb59SThomas Zimmermann  * See also struct &drm_crtc_helper_funcs.atomic_enable.
83*d54dbb59SThomas Zimmermann  */
84*d54dbb59SThomas Zimmermann void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
85*d54dbb59SThomas Zimmermann 				   struct drm_atomic_state *state)
86*d54dbb59SThomas Zimmermann {
87*d54dbb59SThomas Zimmermann 	drm_crtc_vblank_on(crtc);
88*d54dbb59SThomas Zimmermann }
89*d54dbb59SThomas Zimmermann EXPORT_SYMBOL(drm_crtc_vblank_atomic_enable);
90*d54dbb59SThomas Zimmermann 
91*d54dbb59SThomas Zimmermann /**
92*d54dbb59SThomas Zimmermann  * drm_crtc_vblank_atomic_disable - Implements struct &drm_crtc_helper_funcs.atomic_disable
93*d54dbb59SThomas Zimmermann  * @crtc: The CRTC
94*d54dbb59SThomas Zimmermann  * @state: The atomic state
95*d54dbb59SThomas Zimmermann  *
96*d54dbb59SThomas Zimmermann  * The helper drm_crtc_vblank_atomic_disable() implements atomic_disable
97*d54dbb59SThomas Zimmermann  * of struct drm_crtc_helper_funcs for CRTCs the only need to disable VBLANKs.
98*d54dbb59SThomas Zimmermann  *
99*d54dbb59SThomas Zimmermann  * See also struct &drm_crtc_funcs.atomic_disable.
100*d54dbb59SThomas Zimmermann  */
101*d54dbb59SThomas Zimmermann void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
102*d54dbb59SThomas Zimmermann 				    struct drm_atomic_state *state)
103*d54dbb59SThomas Zimmermann {
104*d54dbb59SThomas Zimmermann 	drm_crtc_vblank_off(crtc);
105*d54dbb59SThomas Zimmermann }
106*d54dbb59SThomas Zimmermann EXPORT_SYMBOL(drm_crtc_vblank_atomic_disable);
107*d54dbb59SThomas Zimmermann 
108*d54dbb59SThomas Zimmermann /*
10974afeb81SThomas Zimmermann  * VBLANK timer
11074afeb81SThomas Zimmermann  */
11174afeb81SThomas Zimmermann 
11274afeb81SThomas Zimmermann /**
11374afeb81SThomas Zimmermann  * drm_crtc_vblank_helper_enable_vblank_timer - Implements struct &drm_crtc_funcs.enable_vblank
11474afeb81SThomas Zimmermann  * @crtc: The CRTC
11574afeb81SThomas Zimmermann  *
11674afeb81SThomas Zimmermann  * The helper drm_crtc_vblank_helper_enable_vblank_timer() implements
11774afeb81SThomas Zimmermann  * enable_vblank of struct drm_crtc_helper_funcs for CRTCs that require
11874afeb81SThomas Zimmermann  * a VBLANK timer. It sets up the timer on the first invocation. The
11974afeb81SThomas Zimmermann  * started timer expires after the current frame duration. See struct
12074afeb81SThomas Zimmermann  * &drm_vblank_crtc.framedur_ns.
12174afeb81SThomas Zimmermann  *
12274afeb81SThomas Zimmermann  * See also struct &drm_crtc_helper_funcs.enable_vblank.
12374afeb81SThomas Zimmermann  *
12474afeb81SThomas Zimmermann  * Returns:
12574afeb81SThomas Zimmermann  * 0 on success, or a negative errno code otherwise.
12674afeb81SThomas Zimmermann  */
12774afeb81SThomas Zimmermann int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc)
12874afeb81SThomas Zimmermann {
12974afeb81SThomas Zimmermann 	return drm_crtc_vblank_start_timer(crtc);
13074afeb81SThomas Zimmermann }
13174afeb81SThomas Zimmermann EXPORT_SYMBOL(drm_crtc_vblank_helper_enable_vblank_timer);
13274afeb81SThomas Zimmermann 
13374afeb81SThomas Zimmermann /**
13474afeb81SThomas Zimmermann  * drm_crtc_vblank_helper_disable_vblank_timer - Implements struct &drm_crtc_funcs.disable_vblank
13574afeb81SThomas Zimmermann  * @crtc: The CRTC
13674afeb81SThomas Zimmermann  *
13774afeb81SThomas Zimmermann  * The helper drm_crtc_vblank_helper_disable_vblank_timer() implements
13874afeb81SThomas Zimmermann  * disable_vblank of struct drm_crtc_funcs for CRTCs that require a
13974afeb81SThomas Zimmermann  * VBLANK timer.
14074afeb81SThomas Zimmermann  *
14174afeb81SThomas Zimmermann  * See also struct &drm_crtc_helper_funcs.disable_vblank.
14274afeb81SThomas Zimmermann  */
14374afeb81SThomas Zimmermann void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc)
14474afeb81SThomas Zimmermann {
14574afeb81SThomas Zimmermann 	drm_crtc_vblank_cancel_timer(crtc);
14674afeb81SThomas Zimmermann }
14774afeb81SThomas Zimmermann EXPORT_SYMBOL(drm_crtc_vblank_helper_disable_vblank_timer);
14874afeb81SThomas Zimmermann 
14974afeb81SThomas Zimmermann /**
15074afeb81SThomas Zimmermann  * drm_crtc_vblank_helper_get_vblank_timestamp_from_timer -
15174afeb81SThomas Zimmermann  *	Implements struct &drm_crtc_funcs.get_vblank_timestamp
15274afeb81SThomas Zimmermann  * @crtc: The CRTC
15374afeb81SThomas Zimmermann  * @max_error: Maximum acceptable error
15474afeb81SThomas Zimmermann  * @vblank_time: Returns the next vblank timestamp
15574afeb81SThomas Zimmermann  * @in_vblank_irq: True is called from drm_crtc_handle_vblank()
15674afeb81SThomas Zimmermann  *
15774afeb81SThomas Zimmermann  * The helper drm_crtc_helper_get_vblank_timestamp_from_timer() implements
15874afeb81SThomas Zimmermann  * get_vblank_timestamp of struct drm_crtc_funcs for CRTCs that require a
15974afeb81SThomas Zimmermann  * VBLANK timer. It returns the timestamp according to the timer's expiry
16074afeb81SThomas Zimmermann  * time.
16174afeb81SThomas Zimmermann  *
16274afeb81SThomas Zimmermann  * See also struct &drm_crtc_funcs.get_vblank_timestamp.
16374afeb81SThomas Zimmermann  *
16474afeb81SThomas Zimmermann  * Returns:
16574afeb81SThomas Zimmermann  * True on success, or false otherwise.
16674afeb81SThomas Zimmermann  */
16774afeb81SThomas Zimmermann bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
16874afeb81SThomas Zimmermann 							    int *max_error,
16974afeb81SThomas Zimmermann 							    ktime_t *vblank_time,
17074afeb81SThomas Zimmermann 							    bool in_vblank_irq)
17174afeb81SThomas Zimmermann {
17274afeb81SThomas Zimmermann 	drm_crtc_vblank_get_vblank_timeout(crtc, vblank_time);
17374afeb81SThomas Zimmermann 
17474afeb81SThomas Zimmermann 	return true;
17574afeb81SThomas Zimmermann }
17674afeb81SThomas Zimmermann EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp_from_timer);
177