1 | /* |
2 | * Copyright 2016 Intel Corp. |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
11 | * The above copyright notice and this permission notice (including the next |
12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | */ |
23 | |
24 | #ifndef _DRM_VBLANK_H_ |
25 | #define _DRM_VBLANK_H_ |
26 | |
27 | #include <linux/seqlock.h> |
28 | #include <linux/idr.h> |
29 | #include <linux/poll.h> |
30 | |
31 | #include <drm/drm_file.h> |
32 | #include <drm/drm_modes.h> |
33 | #include <uapi/drm/drm.h> |
34 | |
35 | struct drm_device; |
36 | struct drm_crtc; |
37 | |
38 | /** |
39 | * struct drm_pending_vblank_event - pending vblank event tracking |
40 | */ |
41 | struct drm_pending_vblank_event { |
42 | /** |
43 | * @base: Base structure for tracking pending DRM events. |
44 | */ |
45 | struct drm_pending_event base; |
46 | /** |
47 | * @pipe: drm_crtc_index() of the &drm_crtc this event is for. |
48 | */ |
49 | unsigned int pipe; |
50 | /** |
51 | * @sequence: frame event should be triggered at |
52 | */ |
53 | u64 sequence; |
54 | /** |
55 | * @event: Actual event which will be sent to userspace. |
56 | */ |
57 | union { |
58 | /** |
59 | * @event.base: DRM event base class. |
60 | */ |
61 | struct drm_event base; |
62 | |
63 | /** |
64 | * @event.vbl: |
65 | * |
66 | * Event payload for vblank events, requested through |
67 | * either the MODE_PAGE_FLIP or MODE_ATOMIC IOCTL. Also |
68 | * generated by the legacy WAIT_VBLANK IOCTL, but new userspace |
69 | * should use MODE_QUEUE_SEQUENCE and &event.seq instead. |
70 | */ |
71 | struct drm_event_vblank vbl; |
72 | |
73 | /** |
74 | * @event.seq: Event payload for the MODE_QUEUEU_SEQUENCE IOCTL. |
75 | */ |
76 | struct drm_event_crtc_sequence seq; |
77 | } event; |
78 | }; |
79 | |
80 | /** |
81 | * struct drm_vblank_crtc - vblank tracking for a CRTC |
82 | * |
83 | * This structure tracks the vblank state for one CRTC. |
84 | * |
85 | * Note that for historical reasons - the vblank handling code is still shared |
86 | * with legacy/non-kms drivers - this is a free-standing structure not directly |
87 | * connected to &struct drm_crtc. But all public interface functions are taking |
88 | * a &struct drm_crtc to hide this implementation detail. |
89 | */ |
90 | struct drm_vblank_crtc { |
91 | /** |
92 | * @dev: Pointer to the &drm_device. |
93 | */ |
94 | struct drm_device *dev; |
95 | /** |
96 | * @queue: Wait queue for vblank waiters. |
97 | */ |
98 | wait_queue_head_t queue; |
99 | /** |
100 | * @disable_timer: Disable timer for the delayed vblank disabling |
101 | * hysteresis logic. Vblank disabling is controlled through the |
102 | * drm_vblank_offdelay module option and the setting of the |
103 | * &drm_device.max_vblank_count value. |
104 | */ |
105 | struct timer_list disable_timer; |
106 | |
107 | /** |
108 | * @seqlock: Protect vblank count and time. |
109 | */ |
110 | seqlock_t seqlock; |
111 | |
112 | /** |
113 | * @count: Current software vblank counter. |
114 | */ |
115 | u64 count; |
116 | /** |
117 | * @time: Vblank timestamp corresponding to @count. |
118 | */ |
119 | ktime_t time; |
120 | |
121 | /** |
122 | * @refcount: Number of users/waiters of the vblank interrupt. Only when |
123 | * this refcount reaches 0 can the hardware interrupt be disabled using |
124 | * @disable_timer. |
125 | */ |
126 | atomic_t refcount; |
127 | /** |
128 | * @last: Protected by &drm_device.vbl_lock, used for wraparound handling. |
129 | */ |
130 | u32 last; |
131 | /** |
132 | * @max_vblank_count: |
133 | * |
134 | * Maximum value of the vblank registers for this crtc. This value +1 |
135 | * will result in a wrap-around of the vblank register. It is used |
136 | * by the vblank core to handle wrap-arounds. |
137 | * |
138 | * If set to zero the vblank core will try to guess the elapsed vblanks |
139 | * between times when the vblank interrupt is disabled through |
140 | * high-precision timestamps. That approach is suffering from small |
141 | * races and imprecision over longer time periods, hence exposing a |
142 | * hardware vblank counter is always recommended. |
143 | * |
144 | * This is the runtime configurable per-crtc maximum set through |
145 | * drm_crtc_set_max_vblank_count(). If this is used the driver |
146 | * must leave the device wide &drm_device.max_vblank_count at zero. |
147 | * |
148 | * If non-zero, &drm_crtc_funcs.get_vblank_counter must be set. |
149 | */ |
150 | u32 max_vblank_count; |
151 | /** |
152 | * @inmodeset: Tracks whether the vblank is disabled due to a modeset. |
153 | * For legacy driver bit 2 additionally tracks whether an additional |
154 | * temporary vblank reference has been acquired to paper over the |
155 | * hardware counter resetting/jumping. KMS drivers should instead just |
156 | * call drm_crtc_vblank_off() and drm_crtc_vblank_on(), which explicitly |
157 | * save and restore the vblank count. |
158 | */ |
159 | unsigned int inmodeset; |
160 | /** |
161 | * @pipe: drm_crtc_index() of the &drm_crtc corresponding to this |
162 | * structure. |
163 | */ |
164 | unsigned int pipe; |
165 | /** |
166 | * @framedur_ns: Frame/Field duration in ns, used by |
167 | * drm_calc_vbltimestamp_from_scanoutpos() and computed by |
168 | * drm_calc_timestamping_constants(). |
169 | */ |
170 | int framedur_ns; |
171 | /** |
172 | * @linedur_ns: Line duration in ns, used by |
173 | * drm_calc_vbltimestamp_from_scanoutpos() and computed by |
174 | * drm_calc_timestamping_constants(). |
175 | */ |
176 | int linedur_ns; |
177 | |
178 | /** |
179 | * @hwmode: |
180 | * |
181 | * Cache of the current hardware display mode. Only valid when @enabled |
182 | * is set. This is used by helpers like |
183 | * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the |
184 | * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, |
185 | * because that one is really hard to get from interrupt context. |
186 | */ |
187 | struct drm_display_mode hwmode; |
188 | |
189 | /** |
190 | * @enabled: Tracks the enabling state of the corresponding &drm_crtc to |
191 | * avoid double-disabling and hence corrupting saved state. Needed by |
192 | * drivers not using atomic KMS, since those might go through their CRTC |
193 | * disabling functions multiple times. |
194 | */ |
195 | bool enabled; |
196 | }; |
197 | |
198 | int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); |
199 | u64 drm_crtc_vblank_count(struct drm_crtc *crtc); |
200 | u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, |
201 | ktime_t *vblanktime); |
202 | void drm_crtc_send_vblank_event(struct drm_crtc *crtc, |
203 | struct drm_pending_vblank_event *e); |
204 | void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, |
205 | struct drm_pending_vblank_event *e); |
206 | void drm_vblank_set_event(struct drm_pending_vblank_event *e, |
207 | u64 *seq, |
208 | ktime_t *now); |
209 | bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); |
210 | bool drm_crtc_handle_vblank(struct drm_crtc *crtc); |
211 | int drm_crtc_vblank_get(struct drm_crtc *crtc); |
212 | void drm_crtc_vblank_put(struct drm_crtc *crtc); |
213 | void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); |
214 | void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); |
215 | void drm_crtc_vblank_off(struct drm_crtc *crtc); |
216 | void drm_crtc_vblank_reset(struct drm_crtc *crtc); |
217 | void drm_crtc_vblank_on(struct drm_crtc *crtc); |
218 | u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); |
219 | void drm_vblank_restore(struct drm_device *dev, unsigned int pipe); |
220 | void drm_crtc_vblank_restore(struct drm_crtc *crtc); |
221 | |
222 | bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, |
223 | unsigned int pipe, int *max_error, |
224 | ktime_t *vblank_time, |
225 | bool in_vblank_irq); |
226 | void drm_calc_timestamping_constants(struct drm_crtc *crtc, |
227 | const struct drm_display_mode *mode); |
228 | wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); |
229 | void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, |
230 | u32 max_vblank_count); |
231 | #endif |
232 | |