File Index
Files and directories
Sign in
FILE

drm_vblank_helper.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/drm_vblank_helper.c C
  1// SPDX-License-Identifier: MIT
  2
  3#include <drm/drm_atomic.h>
  4#include <drm/drm_crtc.h>
  5#include <drm/drm_managed.h>
  6#include <drm/drm_modeset_helper_vtables.h>
  7#include <drm/drm_print.h>
  8#include <drm/drm_vblank.h>
  9#include <drm/drm_vblank_helper.h>
 10
 11/**
 12 * DOC: overview
 13 *
 14 * The vblank helper library provides functions for supporting vertical
 15 * blanking in DRM drivers.
 16 *
 17 * For vblank timers, several callback implementations are available.
 18 * Drivers enable support for vblank timers by setting the vblank callbacks
 19 * in struct &drm_crtc_funcs to the helpers provided by this library. The
 20 * initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
 21 * The driver further has to send the VBLANK event from its atomic_flush
 22 * callback and control vblank from the CRTC's atomic_enable and atomic_disable
 23 * callbacks. The callbacks are located in struct &drm_crtc_helper_funcs.
 24 * The vblank helper library provides implementations of these callbacks
 25 * for drivers without further requirements. The initializer macro
 26 * DRM_CRTC_HELPER_VBLANK_FUNCS sets them coveniently.
 27 *
 28 * Once the driver enables vblank support with drm_vblank_init(), each
 29 * CRTC's vblank timer fires according to the programmed display mode. By
 30 * default, the vblank timer invokes drm_crtc_handle_vblank(). Drivers with
 31 * more specific requirements can set their own handler function in
 32 * struct &drm_crtc_helper_funcs.handle_vblank_timeout.
 33 */
 34
 35/*
 36 * VBLANK helpers
 37 */
 38
 39/**
 40 * drm_crtc_vblank_atomic_flush -
 41 *	Implements struct &drm_crtc_helper_funcs.atomic_flush
 42 * @crtc: The CRTC
 43 * @state: The atomic state to apply
 44 *
 45 * The helper drm_crtc_vblank_atomic_flush() implements atomic_flush of
 46 * struct drm_crtc_helper_funcs for CRTCs that only need to send out a
 47 * VBLANK event.
 48 *
 49 * See also struct &drm_crtc_helper_funcs.atomic_flush.
 50 */
 51void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
 52				  struct drm_atomic_state *state)
 53{
 54	struct drm_device *dev = crtc->dev;
 55	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 56	struct drm_pending_vblank_event *event;
 57
 58	spin_lock_irq(&dev->event_lock);
 59
 60	event = crtc_state->event;
 61	crtc_state->event = NULL;
 62
 63	if (event) {
 64		if (drm_crtc_vblank_get(crtc) == 0)
 65			drm_crtc_arm_vblank_event(crtc, event);
 66		else
 67			drm_crtc_send_vblank_event(crtc, event);
 68	}
 69
 70	spin_unlock_irq(&dev->event_lock);
 71}
 72EXPORT_SYMBOL(drm_crtc_vblank_atomic_flush);
 73
 74/**
 75 * drm_crtc_vblank_atomic_enable - Implements struct &drm_crtc_helper_funcs.atomic_enable
 76 * @crtc: The CRTC
 77 * @state: The atomic state
 78 *
 79 * The helper drm_crtc_vblank_atomic_enable() implements atomic_enable
 80 * of struct drm_crtc_helper_funcs for CRTCs the only need to enable VBLANKs.
 81 *
 82 * See also struct &drm_crtc_helper_funcs.atomic_enable.
 83 */
 84void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
 85				   struct drm_atomic_state *state)
 86{
 87	drm_crtc_vblank_on(crtc);
 88}
 89EXPORT_SYMBOL(drm_crtc_vblank_atomic_enable);
 90
 91/**
 92 * drm_crtc_vblank_atomic_disable - Implements struct &drm_crtc_helper_funcs.atomic_disable
 93 * @crtc: The CRTC
 94 * @state: The atomic state
 95 *
 96 * The helper drm_crtc_vblank_atomic_disable() implements atomic_disable
 97 * of struct drm_crtc_helper_funcs for CRTCs the only need to disable VBLANKs.
 98 *
 99 * See also struct &drm_crtc_funcs.atomic_disable.
100 */
101void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
102				    struct drm_atomic_state *state)
103{
104	drm_crtc_vblank_off(crtc);
105}
106EXPORT_SYMBOL(drm_crtc_vblank_atomic_disable);
107
108/*
109 * VBLANK timer
110 */
111
112/**
113 * drm_crtc_vblank_helper_enable_vblank_timer - Implements struct &drm_crtc_funcs.enable_vblank
114 * @crtc: The CRTC
115 *
116 * The helper drm_crtc_vblank_helper_enable_vblank_timer() implements
117 * enable_vblank of struct drm_crtc_helper_funcs for CRTCs that require
118 * a VBLANK timer. It sets up the timer on the first invocation. The
119 * started timer expires after the current frame duration. See struct
120 * &drm_vblank_crtc.framedur_ns.
121 *
122 * See also struct &drm_crtc_helper_funcs.enable_vblank.
123 *
124 * Returns:
125 * 0 on success, or a negative errno code otherwise.
126 */
127int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc)
128{
129	return drm_crtc_vblank_start_timer(crtc);
130}
131EXPORT_SYMBOL(drm_crtc_vblank_helper_enable_vblank_timer);
132
133/**
134 * drm_crtc_vblank_helper_disable_vblank_timer - Implements struct &drm_crtc_funcs.disable_vblank
135 * @crtc: The CRTC
136 *
137 * The helper drm_crtc_vblank_helper_disable_vblank_timer() implements
138 * disable_vblank of struct drm_crtc_funcs for CRTCs that require a
139 * VBLANK timer.
140 *
141 * See also struct &drm_crtc_helper_funcs.disable_vblank.
142 */
143void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc)
144{
145	drm_crtc_vblank_cancel_timer(crtc);
146}
147EXPORT_SYMBOL(drm_crtc_vblank_helper_disable_vblank_timer);
148
149/**
150 * drm_crtc_vblank_helper_get_vblank_timestamp_from_timer -
151 *	Implements struct &drm_crtc_funcs.get_vblank_timestamp
152 * @crtc: The CRTC
153 * @max_error: Maximum acceptable error
154 * @vblank_time: Returns the next vblank timestamp
155 * @in_vblank_irq: True is called from drm_crtc_handle_vblank()
156 *
157 * The helper drm_crtc_helper_get_vblank_timestamp_from_timer() implements
158 * get_vblank_timestamp of struct drm_crtc_funcs for CRTCs that require a
159 * VBLANK timer. It returns the timestamp according to the timer's expiry
160 * time.
161 *
162 * See also struct &drm_crtc_funcs.get_vblank_timestamp.
163 *
164 * Returns:
165 * True on success, or false otherwise.
166 */
167bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
168							    int *max_error,
169							    ktime_t *vblank_time,
170							    bool in_vblank_irq)
171{
172	drm_crtc_vblank_get_vblank_timeout(crtc, vblank_time);
173
174	return true;
175}
176EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp_from_timer);
~/ Read-only file preview.