| 1 | |
| 2 | * drm_irq.c IRQ and vblank support
|
| 3 | *
|
| 4 | * \author Rickard E. (Rik) Faith <[email protected]>
|
| 5 | * \author Gareth Hughes <[email protected]>
|
| 6 | *
|
| 7 | * Permission is hereby granted, free of charge, to any person obtaining a
|
| 8 | * copy of this software and associated documentation files (the "Software"),
|
| 9 | * to deal in the Software without restriction, including without limitation
|
| 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
| 11 | * and/or sell copies of the Software, and to permit persons to whom the
|
| 12 | * Software is furnished to do so, subject to the following conditions:
|
| 13 | *
|
| 14 | * The above copyright notice and this permission notice (including the next
|
| 15 | * paragraph) shall be included in all copies or substantial portions of the
|
| 16 | * Software.
|
| 17 | *
|
| 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
| 21 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
| 22 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
| 23 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 24 | * OTHER DEALINGS IN THE SOFTWARE.
|
| 25 |
|
| 26 |
|
| 27 | #include <linux/export.h>
|
| 28 | #include <linux/kthread.h>
|
| 29 | #include <linux/moduleparam.h>
|
| 30 |
|
| 31 | #include <drm/drm_crtc.h>
|
| 32 | #include <drm/drm_drv.h>
|
| 33 | #include <drm/drm_framebuffer.h>
|
| 34 | #include <drm/drm_managed.h>
|
| 35 | #include <drm/drm_modeset_helper_vtables.h>
|
| 36 | #include <drm/drm_print.h>
|
| 37 | #include <drm/drm_vblank.h>
|
| 38 |
|
| 39 | #include "drm_internal.h"
|
| 40 | #include "drm_trace.h"
|
| 41 |
|
| 42 | |
| 43 | * DOC: vblank handling
|
| 44 | *
|
| 45 | * From the computer's perspective, every time the monitor displays
|
| 46 | * a new frame the scanout engine has "scanned out" the display image
|
| 47 | * from top to bottom, one row of pixels at a time. The current row
|
| 48 | * of pixels is referred to as the current scanline.
|
| 49 | *
|
| 50 | * In addition to the display's visible area, there's usually a couple of
|
| 51 | * extra scanlines which aren't actually displayed on the screen.
|
| 52 | * These extra scanlines don't contain image data and are occasionally used
|
| 53 | * for features like audio and infoframes. The region made up of these
|
| 54 | * scanlines is referred to as the vertical blanking region, or vblank for
|
| 55 | * short.
|
| 56 | *
|
| 57 | * For historical reference, the vertical blanking period was designed to
|
| 58 | * give the electron gun (on CRTs) enough time to move back to the top of
|
| 59 | * the screen to start scanning out the next frame. Similar for horizontal
|
| 60 | * blanking periods. They were designed to give the electron gun enough
|
| 61 | * time to move back to the other side of the screen to start scanning the
|
| 62 | * next scanline.
|
| 63 | *
|
| 64 | * ::
|
| 65 | *
|
| 66 | *
|
| 67 | * physical → ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
|
| 68 | * top of | |
|
| 69 | * display | |
|
| 70 | * | New frame |
|
| 71 | * | |
|
| 72 | * |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|
|
| 73 | * |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ← Scanline,
|
| 74 | * |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓| updates the
|
| 75 | * | | frame as it
|
| 76 | * | | travels down
|
| 77 | * | | ("scan out")
|
| 78 | * | Old frame |
|
| 79 | * | |
|
| 80 | * | |
|
| 81 | * | |
|
| 82 | * | | physical
|
| 83 | * | | bottom of
|
| 84 | * vertical |⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽| ← display
|
| 85 | * blanking ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
|
| 86 | * region → ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
|
| 87 | * ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
|
| 88 | * start of → ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
|
| 89 | * new frame
|
| 90 | *
|
| 91 | * "Physical top of display" is the reference point for the high-precision/
|
| 92 | * corrected timestamp.
|
| 93 | *
|
| 94 | * On a lot of display hardware, programming needs to take effect during the
|
| 95 | * vertical blanking period so that settings like gamma, the image buffer
|
| 96 | * buffer to be scanned out, etc. can safely be changed without showing
|
| 97 | * any visual artifacts on the screen. In some unforgiving hardware, some of
|
| 98 | * this programming has to both start and end in the same vblank. To help
|
| 99 | * with the timing of the hardware programming, an interrupt is usually
|
| 100 | * available to notify the driver when it can start the updating of registers.
|
| 101 | * The interrupt is in this context named the vblank interrupt.
|
| 102 | *
|
| 103 | * The vblank interrupt may be fired at different points depending on the
|
| 104 | * hardware. Some hardware implementations will fire the interrupt when the
|
| 105 | * new frame start, other implementations will fire the interrupt at different
|
| 106 | * points in time.
|
| 107 | *
|
| 108 | * Vertical blanking plays a major role in graphics rendering. To achieve
|
| 109 | * tear-free display, users must synchronize page flips and/or rendering to
|
| 110 | * vertical blanking. The DRM API offers ioctls to perform page flips
|
| 111 | * synchronized to vertical blanking and wait for vertical blanking.
|
| 112 | *
|
| 113 | * The DRM core handles most of the vertical blanking management logic, which
|
| 114 | * involves filtering out spurious interrupts, keeping race-free blanking
|
| 115 | * counters, coping with counter wrap-around and resets and keeping use counts.
|
| 116 | * It relies on the driver to generate vertical blanking interrupts and
|
| 117 | * optionally provide a hardware vertical blanking counter.
|
| 118 | *
|
| 119 | * Drivers must initialize the vertical blanking handling core with a call to
|
| 120 | * drm_vblank_init(). Minimally, a driver needs to implement
|
| 121 | * &drm_crtc_funcs.enable_vblank and &drm_crtc_funcs.disable_vblank plus call
|
| 122 | * drm_crtc_handle_vblank() in its vblank interrupt handler for working vblank
|
| 123 | * support.
|
| 124 | *
|
| 125 | * Vertical blanking interrupts can be enabled by the DRM core or by drivers
|
| 126 | * themselves (for instance to handle page flipping operations). The DRM core
|
| 127 | * maintains a vertical blanking use count to ensure that the interrupts are not
|
| 128 | * disabled while a user still needs them. To increment the use count, drivers
|
| 129 | * call drm_crtc_vblank_get() and release the vblank reference again with
|
| 130 | * drm_crtc_vblank_put(). In between these two calls vblank interrupts are
|
| 131 | * guaranteed to be enabled.
|
| 132 | *
|
| 133 | * On many hardware disabling the vblank interrupt cannot be done in a race-free
|
| 134 | * manner, see &drm_vblank_crtc_config.disable_immediate and
|
| 135 | * &drm_driver.max_vblank_count. In that case the vblank core only disables the
|
| 136 | * vblanks after a timer has expired, which can be configured through the
|
| 137 | * ``vblankoffdelay`` module parameter.
|
| 138 | *
|
| 139 | * Drivers for hardware without support for vertical-blanking interrupts can
|
| 140 | * use DRM vblank timers to send vblank events at the rate of the current
|
| 141 | * display mode's refresh. While not synchronized to the hardware's
|
| 142 | * vertical-blanking regions, the timer helps DRM clients and compositors to
|
| 143 | * adapt their update cycle to the display output. Drivers should set up
|
| 144 | * vblanking as usual, but call drm_crtc_vblank_start_timer() and
|
| 145 | * drm_crtc_vblank_cancel_timer() as part of their atomic mode setting.
|
| 146 | * See also DRM vblank helpers for more information.
|
| 147 | *
|
| 148 | * Drivers without support for vertical-blanking interrupts nor timers must
|
| 149 | * not call drm_vblank_init(). For these drivers, atomic helpers will
|
| 150 | * automatically generate fake vblank events as part of the display update.
|
| 151 | * This functionality also can be controlled by the driver by enabling and
|
| 152 | * disabling struct drm_crtc_state.no_vblank.
|
| 153 |
|
| 154 |
|
| 155 | |
| 156 | * drm_timestamp_precision before giving up.
|
| 157 |
|
| 158 | #define DRM_TIMESTAMP_MAXRETRIES 3
|
| 159 |
|
| 160 | |
| 161 | * vblank irq in drm_handle_vblank(). 1 msec should be ok.
|
| 162 |
|
| 163 | #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
|
| 164 |
|
| 165 | static bool
|
| 166 | drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
|
| 167 | ktime_t *tvblank, bool in_vblank_irq);
|
| 168 |
|
| 169 | static unsigned int drm_timestamp_precision = 20;
|
| 170 |
|
| 171 | static int drm_vblank_offdelay = 5000;
|
| 172 |
|
| 173 | module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
|
| 174 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
|
| 175 | MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)");
|
| 176 | MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
|
| 177 |
|
| 178 | static struct drm_vblank_crtc *
|
| 179 | drm_vblank_crtc(struct drm_device *dev, unsigned int pipe)
|
| 180 | {
|
| 181 | return &dev->vblank[pipe];
|
| 182 | }
|
| 183 |
|
| 184 | struct drm_vblank_crtc *
|
| 185 | drm_crtc_vblank_crtc(struct drm_crtc *crtc)
|
| 186 | {
|
| 187 | return drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
|
| 188 | }
|
| 189 | EXPORT_SYMBOL(drm_crtc_vblank_crtc);
|
| 190 |
|
| 191 | static void store_vblank(struct drm_device *dev, unsigned int pipe,
|
| 192 | u32 vblank_count_inc,
|
| 193 | ktime_t t_vblank, u32 last)
|
| 194 | {
|
| 195 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 196 |
|
| 197 | assert_spin_locked(&dev->vblank_time_lock);
|
| 198 |
|
| 199 | vblank->last = last;
|
| 200 |
|
| 201 | write_seqlock(&vblank->seqlock);
|
| 202 | vblank->time = t_vblank;
|
| 203 | atomic64_add(vblank_count_inc, &vblank->count);
|
| 204 | write_sequnlock(&vblank->seqlock);
|
| 205 | }
|
| 206 |
|
| 207 | static u32 drm_max_vblank_count(struct drm_device *dev, unsigned int pipe)
|
| 208 | {
|
| 209 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 210 |
|
| 211 | return vblank->max_vblank_count ?: dev->max_vblank_count;
|
| 212 | }
|
| 213 |
|
| 214 | |
| 215 | * "No hw counter" fallback implementation of .get_vblank_counter() hook,
|
| 216 | * if there is no usable hardware frame counter available.
|
| 217 |
|
| 218 | static u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe)
|
| 219 | {
|
| 220 | drm_WARN_ON_ONCE(dev, drm_max_vblank_count(dev, pipe) != 0);
|
| 221 | return 0;
|
| 222 | }
|
| 223 |
|
| 224 | static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
|
| 225 | {
|
| 226 | if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
| 227 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
|
| 228 |
|
| 229 | if (drm_WARN_ON(dev, !crtc))
|
| 230 | return 0;
|
| 231 |
|
| 232 | if (crtc->funcs->get_vblank_counter)
|
| 233 | return crtc->funcs->get_vblank_counter(crtc);
|
| 234 | }
|
| 235 |
|
| 236 | return drm_vblank_no_hw_counter(dev, pipe);
|
| 237 | }
|
| 238 |
|
| 239 | static bool get_vblank_counter_and_timestamp(struct drm_device *dev, unsigned int pipe,
|
| 240 | u32 *cur_vblank, ktime_t *t_vblank,
|
| 241 | bool in_vblank_irq)
|
| 242 | {
|
| 243 | int count = DRM_TIMESTAMP_MAXRETRIES;
|
| 244 | bool rc;
|
| 245 |
|
| 246 | do {
|
| 247 | *cur_vblank = __get_vblank_counter(dev, pipe);
|
| 248 | rc = drm_get_last_vbltimestamp(dev, pipe, t_vblank, in_vblank_irq);
|
| 249 | } while (*cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
|
| 250 |
|
| 251 | return rc;
|
| 252 | }
|
| 253 |
|
| 254 | |
| 255 | * Reset the stored timestamp for the current vblank count to correspond
|
| 256 | * to the last vblank occurred.
|
| 257 | *
|
| 258 | * Only to be called from drm_crtc_vblank_on().
|
| 259 | *
|
| 260 | * Note: caller must hold &drm_device.vbl_lock since this reads & writes
|
| 261 | * device vblank fields.
|
| 262 |
|
| 263 | static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe)
|
| 264 | {
|
| 265 | u32 cur_vblank;
|
| 266 | bool rc;
|
| 267 | ktime_t t_vblank;
|
| 268 |
|
| 269 | spin_lock(&dev->vblank_time_lock);
|
| 270 |
|
| 271 | |
| 272 | * sample the current counter to avoid random jumps
|
| 273 | * when drm_vblank_enable() applies the diff
|
| 274 |
|
| 275 | rc = get_vblank_counter_and_timestamp(dev, pipe, &cur_vblank,
|
| 276 | &t_vblank, false);
|
| 277 |
|
| 278 | |
| 279 | * Only reinitialize corresponding vblank timestamp if high-precision query
|
| 280 | * available and didn't fail. Otherwise reinitialize delayed at next vblank
|
| 281 | * interrupt and assign 0 for now, to mark the vblanktimestamp as invalid.
|
| 282 |
|
| 283 | if (!rc)
|
| 284 | t_vblank = 0;
|
| 285 |
|
| 286 | |
| 287 | * +1 to make sure user will never see the same
|
| 288 | * vblank counter value before and after a modeset
|
| 289 |
|
| 290 | store_vblank(dev, pipe, 1, t_vblank, cur_vblank);
|
| 291 |
|
| 292 | spin_unlock(&dev->vblank_time_lock);
|
| 293 | }
|
| 294 |
|
| 295 | |
| 296 | * Call back into the driver to update the appropriate vblank counter
|
| 297 | * (specified by @pipe). Deal with wraparound, if it occurred, and
|
| 298 | * update the last read value so we can deal with wraparound on the next
|
| 299 | * call if necessary.
|
| 300 | *
|
| 301 | * Only necessary when going from off->on, to account for frames we
|
| 302 | * didn't get an interrupt for.
|
| 303 | *
|
| 304 | * Note: caller must hold &drm_device.vbl_lock since this reads & writes
|
| 305 | * device vblank fields.
|
| 306 |
|
| 307 | static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
|
| 308 | bool in_vblank_irq)
|
| 309 | {
|
| 310 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 311 | u32 cur_vblank, diff;
|
| 312 | bool rc;
|
| 313 | ktime_t t_vblank;
|
| 314 | int framedur_ns = vblank->framedur_ns;
|
| 315 | u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
|
| 316 |
|
| 317 | |
| 318 | * Interrupts were disabled prior to this call, so deal with counter
|
| 319 | * wrap if needed.
|
| 320 | * NOTE! It's possible we lost a full dev->max_vblank_count + 1 events
|
| 321 | * here if the register is small or we had vblank interrupts off for
|
| 322 | * a long time.
|
| 323 | *
|
| 324 | * We repeat the hardware vblank counter & timestamp query until
|
| 325 | * we get consistent results. This to prevent races between gpu
|
| 326 | * updating its hardware counter while we are retrieving the
|
| 327 | * corresponding vblank timestamp.
|
| 328 |
|
| 329 | rc = get_vblank_counter_and_timestamp(dev, pipe, &cur_vblank,
|
| 330 | &t_vblank, in_vblank_irq);
|
| 331 |
|
| 332 | if (max_vblank_count) {
|
| 333 |
|
| 334 | diff = (cur_vblank - vblank->last) & max_vblank_count;
|
| 335 | } else if (rc && framedur_ns) {
|
| 336 | u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
|
| 337 |
|
| 338 | |
| 339 | * Figure out how many vblanks we've missed based
|
| 340 | * on the difference in the timestamps and the
|
| 341 | * frame/field duration.
|
| 342 |
|
| 343 |
|
| 344 | drm_dbg_vbl(dev, "crtc %u: Calculating number of vblanks."
|
| 345 | " diff_ns = %lld, framedur_ns = %d)\n",
|
| 346 | pipe, (long long)diff_ns, framedur_ns);
|
| 347 |
|
| 348 | diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
|
| 349 |
|
| 350 | if (diff == 0 && in_vblank_irq)
|
| 351 | drm_dbg_vbl(dev, "crtc %u: Redundant vblirq ignored\n",
|
| 352 | pipe);
|
| 353 | } else {
|
| 354 |
|
| 355 | diff = in_vblank_irq ? 1 : 0;
|
| 356 | }
|
| 357 |
|
| 358 | |
| 359 | * Within a drm_vblank_pre_modeset - drm_vblank_post_modeset
|
| 360 | * interval? If so then vblank irqs keep running and it will likely
|
| 361 | * happen that the hardware vblank counter is not trustworthy as it
|
| 362 | * might reset at some point in that interval and vblank timestamps
|
| 363 | * are not trustworthy either in that interval. Iow. this can result
|
| 364 | * in a bogus diff >> 1 which must be avoided as it would cause
|
| 365 | * random large forward jumps of the software vblank counter.
|
| 366 |
|
| 367 | if (diff > 1 && (vblank->inmodeset & 0x2)) {
|
| 368 | drm_dbg_vbl(dev,
|
| 369 | "clamping vblank bump to 1 on crtc %u: diffr=%u"
|
| 370 | " due to pre-modeset.\n", pipe, diff);
|
| 371 | diff = 1;
|
| 372 | }
|
| 373 |
|
| 374 | drm_dbg_vbl(dev, "updating vblank count on crtc %u:"
|
| 375 | " current=%llu, diff=%u, hw=%u hw_last=%u\n",
|
| 376 | pipe, (unsigned long long)atomic64_read(&vblank->count),
|
| 377 | diff, cur_vblank, vblank->last);
|
| 378 |
|
| 379 | if (diff == 0) {
|
| 380 | drm_WARN_ON_ONCE(dev, cur_vblank != vblank->last);
|
| 381 | return;
|
| 382 | }
|
| 383 |
|
| 384 | |
| 385 | * Only reinitialize corresponding vblank timestamp if high-precision query
|
| 386 | * available and didn't fail, or we were called from the vblank interrupt.
|
| 387 | * Otherwise reinitialize delayed at next vblank interrupt and assign 0
|
| 388 | * for now, to mark the vblanktimestamp as invalid.
|
| 389 |
|
| 390 | if (!rc && !in_vblank_irq)
|
| 391 | t_vblank = 0;
|
| 392 |
|
| 393 | store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
|
| 394 | }
|
| 395 |
|
| 396 | u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
|
| 397 | {
|
| 398 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 399 | u64 count;
|
| 400 |
|
| 401 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 402 | return 0;
|
| 403 |
|
| 404 | count = atomic64_read(&vblank->count);
|
| 405 |
|
| 406 | |
| 407 | * This read barrier corresponds to the implicit write barrier of the
|
| 408 | * write seqlock in store_vblank(). Note that this is the only place
|
| 409 | * where we need an explicit barrier, since all other access goes
|
| 410 | * through drm_vblank_count_and_time(), which already has the required
|
| 411 | * read barrier curtesy of the read seqlock.
|
| 412 |
|
| 413 | smp_rmb();
|
| 414 |
|
| 415 | return count;
|
| 416 | }
|
| 417 |
|
| 418 | |
| 419 | * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
|
| 420 | * @crtc: which counter to retrieve
|
| 421 | *
|
| 422 | * This function is similar to drm_crtc_vblank_count() but this function
|
| 423 | * interpolates to handle a race with vblank interrupts using the high precision
|
| 424 | * timestamping support.
|
| 425 | *
|
| 426 | * This is mostly useful for hardware that can obtain the scanout position, but
|
| 427 | * doesn't have a hardware frame counter.
|
| 428 |
|
| 429 | u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
|
| 430 | {
|
| 431 | struct drm_device *dev = crtc->dev;
|
| 432 | unsigned int pipe = drm_crtc_index(crtc);
|
| 433 | u64 vblank;
|
| 434 | unsigned long flags;
|
| 435 |
|
| 436 | drm_WARN_ONCE(dev, drm_debug_enabled(DRM_UT_VBL) &&
|
| 437 | !crtc->funcs->get_vblank_timestamp,
|
| 438 | "This function requires support for accurate vblank timestamps.");
|
| 439 |
|
| 440 | spin_lock_irqsave(&dev->vblank_time_lock, flags);
|
| 441 |
|
| 442 | drm_update_vblank_count(dev, pipe, false);
|
| 443 | vblank = drm_vblank_count(dev, pipe);
|
| 444 |
|
| 445 | spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
|
| 446 |
|
| 447 | return vblank;
|
| 448 | }
|
| 449 | EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
|
| 450 |
|
| 451 | static void __disable_vblank(struct drm_device *dev, unsigned int pipe)
|
| 452 | {
|
| 453 | if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
| 454 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
|
| 455 |
|
| 456 | if (drm_WARN_ON(dev, !crtc))
|
| 457 | return;
|
| 458 |
|
| 459 | if (crtc->funcs->disable_vblank)
|
| 460 | crtc->funcs->disable_vblank(crtc);
|
| 461 | }
|
| 462 | }
|
| 463 |
|
| 464 | |
| 465 | * Disable vblank irq's on crtc, make sure that last vblank count
|
| 466 | * of hardware and corresponding consistent software vblank counter
|
| 467 | * are preserved, even if there are any spurious vblank irq's after
|
| 468 | * disable.
|
| 469 |
|
| 470 | void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
|
| 471 | {
|
| 472 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 473 | unsigned long irqflags;
|
| 474 |
|
| 475 | assert_spin_locked(&dev->vbl_lock);
|
| 476 |
|
| 477 | |
| 478 | * so no updates of timestamps or count can happen after we've
|
| 479 | * disabled. Needed to prevent races in case of delayed irq's.
|
| 480 |
|
| 481 | spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
|
| 482 |
|
| 483 | |
| 484 | * Update vblank count and disable vblank interrupts only if the
|
| 485 | * interrupts were enabled. This avoids calling the ->disable_vblank()
|
| 486 | * operation in atomic context with the hardware potentially runtime
|
| 487 | * suspended.
|
| 488 |
|
| 489 | if (!vblank->enabled)
|
| 490 | goto out;
|
| 491 |
|
| 492 | |
| 493 | * Update the count and timestamp to maintain the
|
| 494 | * appearance that the counter has been ticking all along until
|
| 495 | * this time. This makes the count account for the entire time
|
| 496 | * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
|
| 497 |
|
| 498 | drm_update_vblank_count(dev, pipe, false);
|
| 499 | __disable_vblank(dev, pipe);
|
| 500 | vblank->enabled = false;
|
| 501 |
|
| 502 | out:
|
| 503 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
|
| 504 | }
|
| 505 |
|
| 506 | static void vblank_disable_fn(struct timer_list *t)
|
| 507 | {
|
| 508 | struct drm_vblank_crtc *vblank = timer_container_of(vblank, t,
|
| 509 | disable_timer);
|
| 510 | struct drm_device *dev = vblank->dev;
|
| 511 | unsigned int pipe = vblank->pipe;
|
| 512 | unsigned long irqflags;
|
| 513 |
|
| 514 | spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
| 515 | if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
|
| 516 | drm_dbg_core(dev, "disabling vblank on crtc %u\n", pipe);
|
| 517 | drm_vblank_disable_and_save(dev, pipe);
|
| 518 | }
|
| 519 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
| 520 | }
|
| 521 |
|
| 522 | static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
|
| 523 | {
|
| 524 | struct drm_vblank_crtc *vblank = ptr;
|
| 525 |
|
| 526 | drm_WARN_ON(dev, READ_ONCE(vblank->enabled) &&
|
| 527 | drm_core_check_feature(dev, DRIVER_MODESET));
|
| 528 |
|
| 529 | if (vblank->vblank_timer.crtc)
|
| 530 | hrtimer_cancel(&vblank->vblank_timer.timer);
|
| 531 |
|
| 532 | drm_vblank_destroy_worker(vblank);
|
| 533 | timer_delete_sync(&vblank->disable_timer);
|
| 534 | }
|
| 535 |
|
| 536 | |
| 537 | * drm_vblank_init - initialize vblank support
|
| 538 | * @dev: DRM device
|
| 539 | * @num_crtcs: number of CRTCs supported by @dev
|
| 540 | *
|
| 541 | * This function initializes vblank support for @num_crtcs display pipelines.
|
| 542 | * Cleanup is handled automatically through a cleanup function added with
|
| 543 | * drmm_add_action_or_reset().
|
| 544 | *
|
| 545 | * Returns:
|
| 546 | * Zero on success or a negative error code on failure.
|
| 547 |
|
| 548 | int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
|
| 549 | {
|
| 550 | int ret;
|
| 551 | unsigned int i;
|
| 552 |
|
| 553 | spin_lock_init(&dev->vbl_lock);
|
| 554 | spin_lock_init(&dev->vblank_time_lock);
|
| 555 |
|
| 556 | dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
|
| 557 | if (!dev->vblank)
|
| 558 | return -ENOMEM;
|
| 559 |
|
| 560 | dev->num_crtcs = num_crtcs;
|
| 561 |
|
| 562 | for (i = 0; i < num_crtcs; i++) {
|
| 563 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, i);
|
| 564 |
|
| 565 | vblank->dev = dev;
|
| 566 | vblank->pipe = i;
|
| 567 | init_waitqueue_head(&vblank->queue);
|
| 568 | timer_setup(&vblank->disable_timer, vblank_disable_fn, 0);
|
| 569 | seqlock_init(&vblank->seqlock);
|
| 570 |
|
| 571 | ret = drmm_add_action_or_reset(dev, drm_vblank_init_release,
|
| 572 | vblank);
|
| 573 | if (ret)
|
| 574 | return ret;
|
| 575 |
|
| 576 | ret = drm_vblank_worker_init(vblank);
|
| 577 | if (ret)
|
| 578 | return ret;
|
| 579 | }
|
| 580 |
|
| 581 | return 0;
|
| 582 | }
|
| 583 | EXPORT_SYMBOL(drm_vblank_init);
|
| 584 |
|
| 585 | |
| 586 | * drm_dev_has_vblank - test if vblanking has been initialized for
|
| 587 | * a device
|
| 588 | * @dev: the device
|
| 589 | *
|
| 590 | * Drivers may call this function to test if vblank support is
|
| 591 | * initialized for a device. For most hardware this means that vblanking
|
| 592 | * can also be enabled.
|
| 593 | *
|
| 594 | * Atomic helpers use this function to initialize
|
| 595 | * &drm_crtc_state.no_vblank. See also drm_atomic_helper_check_modeset().
|
| 596 | *
|
| 597 | * Returns:
|
| 598 | * True if vblanking has been initialized for the given device, false
|
| 599 | * otherwise.
|
| 600 |
|
| 601 | bool drm_dev_has_vblank(const struct drm_device *dev)
|
| 602 | {
|
| 603 | return dev->num_crtcs != 0;
|
| 604 | }
|
| 605 | EXPORT_SYMBOL(drm_dev_has_vblank);
|
| 606 |
|
| 607 | |
| 608 | * drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC
|
| 609 | * @crtc: which CRTC's vblank waitqueue to retrieve
|
| 610 | *
|
| 611 | * This function returns a pointer to the vblank waitqueue for the CRTC.
|
| 612 | * Drivers can use this to implement vblank waits using wait_event() and related
|
| 613 | * functions.
|
| 614 |
|
| 615 | wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc)
|
| 616 | {
|
| 617 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 618 |
|
| 619 | return &vblank->queue;
|
| 620 | }
|
| 621 | EXPORT_SYMBOL(drm_crtc_vblank_waitqueue);
|
| 622 |
|
| 623 |
|
| 624 | |
| 625 | * drm_calc_timestamping_constants - calculate vblank timestamp constants
|
| 626 | * @crtc: drm_crtc whose timestamp constants should be updated.
|
| 627 | * @mode: display mode containing the scanout timings
|
| 628 | *
|
| 629 | * Calculate and store various constants which are later needed by vblank and
|
| 630 | * swap-completion timestamping, e.g, by
|
| 631 | * drm_crtc_vblank_helper_get_vblank_timestamp(). They are derived from
|
| 632 | * CRTC's true scanout timing, so they take things like panel scaling or
|
| 633 | * other adjustments into account.
|
| 634 |
|
| 635 | void drm_calc_timestamping_constants(struct drm_crtc *crtc,
|
| 636 | const struct drm_display_mode *mode)
|
| 637 | {
|
| 638 | struct drm_device *dev = crtc->dev;
|
| 639 | unsigned int pipe = drm_crtc_index(crtc);
|
| 640 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 641 | int linedur_ns = 0, framedur_ns = 0;
|
| 642 | int dotclock = mode->crtc_clock;
|
| 643 |
|
| 644 | if (!drm_dev_has_vblank(dev))
|
| 645 | return;
|
| 646 |
|
| 647 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 648 | return;
|
| 649 |
|
| 650 |
|
| 651 | if (dotclock > 0) {
|
| 652 | int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
|
| 653 |
|
| 654 | |
| 655 | * Convert scanline length in pixels and video
|
| 656 | * dot clock to line duration and frame duration
|
| 657 | * in nanoseconds:
|
| 658 |
|
| 659 | linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
|
| 660 | framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
|
| 661 |
|
| 662 | |
| 663 | * Fields of interlaced scanout modes are only half a frame duration.
|
| 664 |
|
| 665 | if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
| 666 | framedur_ns /= 2;
|
| 667 | } else {
|
| 668 | drm_err(dev, "crtc %u: Can't calculate constants, dotclock = 0!\n",
|
| 669 | crtc->base.id);
|
| 670 | }
|
| 671 |
|
| 672 | vblank->linedur_ns = linedur_ns;
|
| 673 | vblank->framedur_ns = framedur_ns;
|
| 674 | drm_mode_copy(&vblank->hwmode, mode);
|
| 675 |
|
| 676 | drm_dbg_core(dev,
|
| 677 | "crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
|
| 678 | crtc->base.id, mode->crtc_htotal,
|
| 679 | mode->crtc_vtotal, mode->crtc_vdisplay);
|
| 680 | drm_dbg_core(dev, "crtc %u: clock %d kHz framedur %d linedur %d\n",
|
| 681 | crtc->base.id, dotclock, framedur_ns, linedur_ns);
|
| 682 | }
|
| 683 | EXPORT_SYMBOL(drm_calc_timestamping_constants);
|
| 684 |
|
| 685 | |
| 686 | * drm_crtc_vblank_helper_get_vblank_timestamp_internal - precise vblank
|
| 687 | * timestamp helper
|
| 688 | * @crtc: CRTC whose vblank timestamp to retrieve
|
| 689 | * @max_error: Desired maximum allowable error in timestamps (nanosecs)
|
| 690 | * On return contains true maximum error of timestamp
|
| 691 | * @vblank_time: Pointer to time which should receive the timestamp
|
| 692 | * @in_vblank_irq:
|
| 693 | * True when called from drm_crtc_handle_vblank(). Some drivers
|
| 694 | * need to apply some workarounds for gpu-specific vblank irq quirks
|
| 695 | * if flag is set.
|
| 696 | * @get_scanout_position:
|
| 697 | * Callback function to retrieve the scanout position. See
|
| 698 | * @struct drm_crtc_helper_funcs.get_scanout_position.
|
| 699 | *
|
| 700 | * Implements calculation of exact vblank timestamps from given drm_display_mode
|
| 701 | * timings and current video scanout position of a CRTC.
|
| 702 | *
|
| 703 | * The current implementation only handles standard video modes. For double scan
|
| 704 | * and interlaced modes the driver is supposed to adjust the hardware mode
|
| 705 | * (taken from &drm_crtc_state.adjusted mode for atomic modeset drivers) to
|
| 706 | * match the scanout position reported.
|
| 707 | *
|
| 708 | * Note that atomic drivers must call drm_calc_timestamping_constants() before
|
| 709 | * enabling a CRTC. The atomic helpers already take care of that in
|
| 710 | * drm_atomic_helper_calc_timestamping_constants().
|
| 711 | *
|
| 712 | * Returns:
|
| 713 | * Returns true on success, and false on failure, i.e. when no accurate
|
| 714 | * timestamp could be acquired.
|
| 715 |
|
| 716 | bool
|
| 717 | drm_crtc_vblank_helper_get_vblank_timestamp_internal(
|
| 718 | struct drm_crtc *crtc, int *max_error, ktime_t *vblank_time,
|
| 719 | bool in_vblank_irq,
|
| 720 | drm_vblank_get_scanout_position_func get_scanout_position)
|
| 721 | {
|
| 722 | struct drm_device *dev = crtc->dev;
|
| 723 | unsigned int pipe = crtc->index;
|
| 724 | struct timespec64 ts_etime, ts_vblank_time;
|
| 725 | ktime_t stime, etime;
|
| 726 | bool vbl_status;
|
| 727 | const struct drm_display_mode *mode;
|
| 728 | int vpos, hpos, i;
|
| 729 | int delta_ns, duration_ns;
|
| 730 |
|
| 731 | if (pipe >= dev->num_crtcs) {
|
| 732 | drm_err(dev, "Invalid crtc %u\n", pipe);
|
| 733 | return false;
|
| 734 | }
|
| 735 |
|
| 736 |
|
| 737 | if (!get_scanout_position) {
|
| 738 | drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
|
| 739 | return false;
|
| 740 | }
|
| 741 |
|
| 742 | if (drm_drv_uses_atomic_modeset(dev)) {
|
| 743 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 744 |
|
| 745 | mode = &vblank->hwmode;
|
| 746 | } else {
|
| 747 | mode = &crtc->hwmode;
|
| 748 | }
|
| 749 |
|
| 750 | |
| 751 | * Happens during initial modesetting of a crtc.
|
| 752 |
|
| 753 | if (mode->crtc_clock == 0) {
|
| 754 | drm_dbg_core(dev, "crtc %u: Noop due to uninitialized mode.\n",
|
| 755 | pipe);
|
| 756 | drm_WARN_ON_ONCE(dev, drm_drv_uses_atomic_modeset(dev));
|
| 757 | return false;
|
| 758 | }
|
| 759 |
|
| 760 | |
| 761 | * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times
|
| 762 | * if single query takes longer than max_error nanoseconds.
|
| 763 | *
|
| 764 | * This guarantees a tight bound on maximum error if
|
| 765 | * code gets preempted or delayed for some reason.
|
| 766 |
|
| 767 | for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) {
|
| 768 | |
| 769 | * Get vertical and horizontal scanout position vpos, hpos,
|
| 770 | * and bounding timestamps stime, etime, pre/post query.
|
| 771 |
|
| 772 | vbl_status = get_scanout_position(crtc, in_vblank_irq,
|
| 773 | &vpos, &hpos,
|
| 774 | &stime, &etime,
|
| 775 | mode);
|
| 776 |
|
| 777 |
|
| 778 | if (!vbl_status) {
|
| 779 | drm_dbg_core(dev,
|
| 780 | "crtc %u : scanoutpos query failed.\n",
|
| 781 | pipe);
|
| 782 | return false;
|
| 783 | }
|
| 784 |
|
| 785 |
|
| 786 | duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
|
| 787 |
|
| 788 |
|
| 789 | if (duration_ns <= *max_error)
|
| 790 | break;
|
| 791 | }
|
| 792 |
|
| 793 |
|
| 794 | if (i == DRM_TIMESTAMP_MAXRETRIES) {
|
| 795 | drm_dbg_core(dev,
|
| 796 | "crtc %u: Noisy timestamp %d us > %d us [%d reps].\n",
|
| 797 | pipe, duration_ns / 1000, *max_error / 1000, i);
|
| 798 | }
|
| 799 |
|
| 800 |
|
| 801 | *max_error = duration_ns;
|
| 802 |
|
| 803 | |
| 804 | * since start of scanout at first display scanline. delta_ns
|
| 805 | * can be negative if start of scanout hasn't happened yet.
|
| 806 |
|
| 807 | delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos),
|
| 808 | mode->crtc_clock);
|
| 809 |
|
| 810 | |
| 811 | * vblank_time timestamp for end of vblank.
|
| 812 |
|
| 813 | *vblank_time = ktime_sub_ns(etime, delta_ns);
|
| 814 |
|
| 815 | if (!drm_debug_enabled(DRM_UT_VBL))
|
| 816 | return true;
|
| 817 |
|
| 818 | ts_etime = ktime_to_timespec64(etime);
|
| 819 | ts_vblank_time = ktime_to_timespec64(*vblank_time);
|
| 820 |
|
| 821 | drm_dbg_vbl(dev,
|
| 822 | "crtc %u : v p(%d,%d)@ %ptSp -> %ptSp [e %d us, %d rep]\n",
|
| 823 | pipe, hpos, vpos, &ts_etime, &ts_vblank_time,
|
| 824 | duration_ns / 1000, i);
|
| 825 |
|
| 826 | return true;
|
| 827 | }
|
| 828 | EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp_internal);
|
| 829 |
|
| 830 | |
| 831 | * drm_crtc_vblank_helper_get_vblank_timestamp - precise vblank timestamp
|
| 832 | * helper
|
| 833 | * @crtc: CRTC whose vblank timestamp to retrieve
|
| 834 | * @max_error: Desired maximum allowable error in timestamps (nanosecs)
|
| 835 | * On return contains true maximum error of timestamp
|
| 836 | * @vblank_time: Pointer to time which should receive the timestamp
|
| 837 | * @in_vblank_irq:
|
| 838 | * True when called from drm_crtc_handle_vblank(). Some drivers
|
| 839 | * need to apply some workarounds for gpu-specific vblank irq quirks
|
| 840 | * if flag is set.
|
| 841 | *
|
| 842 | * Implements calculation of exact vblank timestamps from given drm_display_mode
|
| 843 | * timings and current video scanout position of a CRTC. This can be directly
|
| 844 | * used as the &drm_crtc_funcs.get_vblank_timestamp implementation of a kms
|
| 845 | * driver if &drm_crtc_helper_funcs.get_scanout_position is implemented.
|
| 846 | *
|
| 847 | * The current implementation only handles standard video modes. For double scan
|
| 848 | * and interlaced modes the driver is supposed to adjust the hardware mode
|
| 849 | * (taken from &drm_crtc_state.adjusted mode for atomic modeset drivers) to
|
| 850 | * match the scanout position reported.
|
| 851 | *
|
| 852 | * Note that atomic drivers must call drm_calc_timestamping_constants() before
|
| 853 | * enabling a CRTC. The atomic helpers already take care of that in
|
| 854 | * drm_atomic_helper_calc_timestamping_constants().
|
| 855 | *
|
| 856 | * Returns:
|
| 857 | * Returns true on success, and false on failure, i.e. when no accurate
|
| 858 | * timestamp could be acquired.
|
| 859 |
|
| 860 | bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc,
|
| 861 | int *max_error,
|
| 862 | ktime_t *vblank_time,
|
| 863 | bool in_vblank_irq)
|
| 864 | {
|
| 865 | return drm_crtc_vblank_helper_get_vblank_timestamp_internal(
|
| 866 | crtc, max_error, vblank_time, in_vblank_irq,
|
| 867 | crtc->helper_private->get_scanout_position);
|
| 868 | }
|
| 869 | EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp);
|
| 870 |
|
| 871 | |
| 872 | * drm_crtc_get_last_vbltimestamp - retrieve raw timestamp for the most
|
| 873 | * recent vblank interval
|
| 874 | * @crtc: CRTC whose vblank timestamp to retrieve
|
| 875 | * @tvblank: Pointer to target time which should receive the timestamp
|
| 876 | * @in_vblank_irq:
|
| 877 | * True when called from drm_crtc_handle_vblank(). Some drivers
|
| 878 | * need to apply some workarounds for gpu-specific vblank irq quirks
|
| 879 | * if flag is set.
|
| 880 | *
|
| 881 | * Fetches the system timestamp corresponding to the time of the most recent
|
| 882 | * vblank interval on specified CRTC. May call into kms-driver to
|
| 883 | * compute the timestamp with a high-precision GPU specific method.
|
| 884 | *
|
| 885 | * Returns zero if timestamp originates from uncorrected do_gettimeofday()
|
| 886 | * call, i.e., it isn't very precisely locked to the true vblank.
|
| 887 | *
|
| 888 | * Returns:
|
| 889 | * True if timestamp is considered to be very precise, false otherwise.
|
| 890 |
|
| 891 | static bool
|
| 892 | drm_crtc_get_last_vbltimestamp(struct drm_crtc *crtc, ktime_t *tvblank,
|
| 893 | bool in_vblank_irq)
|
| 894 | {
|
| 895 | bool ret = false;
|
| 896 |
|
| 897 |
|
| 898 | int max_error = (int) drm_timestamp_precision * 1000;
|
| 899 |
|
| 900 |
|
| 901 | if (crtc && crtc->funcs->get_vblank_timestamp && max_error > 0) {
|
| 902 | ret = crtc->funcs->get_vblank_timestamp(crtc, &max_error,
|
| 903 | tvblank, in_vblank_irq);
|
| 904 | }
|
| 905 |
|
| 906 | |
| 907 | * Return current monotonic/gettimeofday timestamp as best estimate.
|
| 908 |
|
| 909 | if (!ret)
|
| 910 | *tvblank = ktime_get();
|
| 911 |
|
| 912 | return ret;
|
| 913 | }
|
| 914 |
|
| 915 | static bool
|
| 916 | drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
|
| 917 | ktime_t *tvblank, bool in_vblank_irq)
|
| 918 | {
|
| 919 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
|
| 920 |
|
| 921 | return drm_crtc_get_last_vbltimestamp(crtc, tvblank, in_vblank_irq);
|
| 922 | }
|
| 923 |
|
| 924 | |
| 925 | * drm_crtc_vblank_count - retrieve "cooked" vblank counter value
|
| 926 | * @crtc: which counter to retrieve
|
| 927 | *
|
| 928 | * Fetches the "cooked" vblank count value that represents the number of
|
| 929 | * vblank events since the system was booted, including lost events due to
|
| 930 | * modesetting activity. Note that this timer isn't correct against a racing
|
| 931 | * vblank interrupt (since it only reports the software vblank counter), see
|
| 932 | * drm_crtc_accurate_vblank_count() for such use-cases.
|
| 933 | *
|
| 934 | * Note that for a given vblank counter value drm_crtc_handle_vblank()
|
| 935 | * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time()
|
| 936 | * provide a barrier: Any writes done before calling
|
| 937 | * drm_crtc_handle_vblank() will be visible to callers of the later
|
| 938 | * functions, if the vblank count is the same or a later one.
|
| 939 | *
|
| 940 | * See also &drm_vblank_crtc.count.
|
| 941 | *
|
| 942 | * Returns:
|
| 943 | * The software vblank counter.
|
| 944 |
|
| 945 | u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
|
| 946 | {
|
| 947 | return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
|
| 948 | }
|
| 949 | EXPORT_SYMBOL(drm_crtc_vblank_count);
|
| 950 |
|
| 951 | |
| 952 | * drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the
|
| 953 | * system timestamp corresponding to that vblank counter value.
|
| 954 | * @dev: DRM device
|
| 955 | * @pipe: index of CRTC whose counter to retrieve
|
| 956 | * @vblanktime: Pointer to ktime_t to receive the vblank timestamp.
|
| 957 | *
|
| 958 | * Fetches the "cooked" vblank count value that represents the number of
|
| 959 | * vblank events since the system was booted, including lost events due to
|
| 960 | * modesetting activity. Returns corresponding system timestamp of the time
|
| 961 | * of the vblank interval that corresponds to the current vblank counter value.
|
| 962 | *
|
| 963 | * This is the legacy version of drm_crtc_vblank_count_and_time().
|
| 964 |
|
| 965 | static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
|
| 966 | ktime_t *vblanktime)
|
| 967 | {
|
| 968 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 969 | u64 vblank_count;
|
| 970 | unsigned int seq;
|
| 971 |
|
| 972 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) {
|
| 973 | *vblanktime = 0;
|
| 974 | return 0;
|
| 975 | }
|
| 976 |
|
| 977 | do {
|
| 978 | seq = read_seqbegin(&vblank->seqlock);
|
| 979 | vblank_count = atomic64_read(&vblank->count);
|
| 980 | *vblanktime = vblank->time;
|
| 981 | } while (read_seqretry(&vblank->seqlock, seq));
|
| 982 |
|
| 983 | return vblank_count;
|
| 984 | }
|
| 985 |
|
| 986 | |
| 987 | * drm_crtc_vblank_count_and_time - retrieve "cooked" vblank counter value
|
| 988 | * and the system timestamp corresponding to that vblank counter value
|
| 989 | * @crtc: which counter to retrieve
|
| 990 | * @vblanktime: Pointer to time to receive the vblank timestamp.
|
| 991 | *
|
| 992 | * Fetches the "cooked" vblank count value that represents the number of
|
| 993 | * vblank events since the system was booted, including lost events due to
|
| 994 | * modesetting activity. Returns corresponding system timestamp of the time
|
| 995 | * of the vblank interval that corresponds to the current vblank counter value.
|
| 996 | *
|
| 997 | * Note that for a given vblank counter value drm_crtc_handle_vblank()
|
| 998 | * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time()
|
| 999 | * provide a barrier: Any writes done before calling
|
| 1000 | * drm_crtc_handle_vblank() will be visible to callers of the later
|
| 1001 | * functions, if the vblank count is the same or a later one.
|
| 1002 | *
|
| 1003 | * See also &drm_vblank_crtc.count.
|
| 1004 |
|
| 1005 | u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
|
| 1006 | ktime_t *vblanktime)
|
| 1007 | {
|
| 1008 | return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc),
|
| 1009 | vblanktime);
|
| 1010 | }
|
| 1011 | EXPORT_SYMBOL(drm_crtc_vblank_count_and_time);
|
| 1012 |
|
| 1013 | |
| 1014 | * drm_crtc_next_vblank_start - calculate the time of the next vblank
|
| 1015 | * @crtc: the crtc for which to calculate next vblank time
|
| 1016 | * @vblanktime: pointer to time to receive the next vblank timestamp.
|
| 1017 | *
|
| 1018 | * Calculate the expected time of the start of the next vblank period,
|
| 1019 | * based on time of previous vblank and frame duration
|
| 1020 |
|
| 1021 | int drm_crtc_next_vblank_start(struct drm_crtc *crtc, ktime_t *vblanktime)
|
| 1022 | {
|
| 1023 | struct drm_vblank_crtc *vblank;
|
| 1024 | struct drm_display_mode *mode;
|
| 1025 | u64 vblank_start;
|
| 1026 |
|
| 1027 | if (!drm_dev_has_vblank(crtc->dev))
|
| 1028 | return -EINVAL;
|
| 1029 |
|
| 1030 | vblank = drm_crtc_vblank_crtc(crtc);
|
| 1031 | mode = &vblank->hwmode;
|
| 1032 |
|
| 1033 | if (!vblank->framedur_ns || !vblank->linedur_ns)
|
| 1034 | return -EINVAL;
|
| 1035 |
|
| 1036 | if (!drm_crtc_get_last_vbltimestamp(crtc, vblanktime, false))
|
| 1037 | return -EINVAL;
|
| 1038 |
|
| 1039 | vblank_start = DIV_ROUND_DOWN_ULL(
|
| 1040 | (u64)vblank->framedur_ns * mode->crtc_vblank_start,
|
| 1041 | mode->crtc_vtotal);
|
| 1042 | *vblanktime = ktime_add(*vblanktime, ns_to_ktime(vblank_start));
|
| 1043 |
|
| 1044 | return 0;
|
| 1045 | }
|
| 1046 | EXPORT_SYMBOL(drm_crtc_next_vblank_start);
|
| 1047 |
|
| 1048 | static void send_vblank_event(struct drm_device *dev,
|
| 1049 | struct drm_pending_vblank_event *e,
|
| 1050 | u64 seq, ktime_t now)
|
| 1051 | {
|
| 1052 | struct timespec64 tv;
|
| 1053 |
|
| 1054 | switch (e->event.base.type) {
|
| 1055 | case DRM_EVENT_VBLANK:
|
| 1056 | case DRM_EVENT_FLIP_COMPLETE:
|
| 1057 | tv = ktime_to_timespec64(now);
|
| 1058 | e->event.vbl.sequence = seq;
|
| 1059 | |
| 1060 | * e->event is a user space structure, with hardcoded unsigned
|
| 1061 | * 32-bit seconds/microseconds. This is safe as we always use
|
| 1062 | * monotonic timestamps since linux-4.15
|
| 1063 |
|
| 1064 | e->event.vbl.tv_sec = tv.tv_sec;
|
| 1065 | e->event.vbl.tv_usec = tv.tv_nsec / 1000;
|
| 1066 | break;
|
| 1067 | case DRM_EVENT_CRTC_SEQUENCE:
|
| 1068 | if (seq)
|
| 1069 | e->event.seq.sequence = seq;
|
| 1070 | e->event.seq.time_ns = ktime_to_ns(now);
|
| 1071 | break;
|
| 1072 | }
|
| 1073 | trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq);
|
| 1074 | |
| 1075 | * Use the same timestamp for any associated fence signal to avoid
|
| 1076 | * mismatch in timestamps for vsync & fence events triggered by the
|
| 1077 | * same HW event. Frameworks like SurfaceFlinger in Android expects the
|
| 1078 | * retire-fence timestamp to match exactly with HW vsync as it uses it
|
| 1079 | * for its software vsync modeling.
|
| 1080 |
|
| 1081 | drm_send_event_timestamp_locked(dev, &e->base, now);
|
| 1082 | }
|
| 1083 |
|
| 1084 | |
| 1085 | * drm_crtc_arm_vblank_event - arm vblank event after pageflip
|
| 1086 | * @crtc: the source CRTC of the vblank event
|
| 1087 | * @e: the event to send
|
| 1088 | *
|
| 1089 | * A lot of drivers need to generate vblank events for the very next vblank
|
| 1090 | * interrupt. For example when the page flip interrupt happens when the page
|
| 1091 | * flip gets armed, but not when it actually executes within the next vblank
|
| 1092 | * period. This helper function implements exactly the required vblank arming
|
| 1093 | * behaviour.
|
| 1094 | *
|
| 1095 | * NOTE: Drivers using this to send out the &drm_crtc_state.event as part of an
|
| 1096 | * atomic commit must ensure that the next vblank happens at exactly the same
|
| 1097 | * time as the atomic commit is committed to the hardware. This function itself
|
| 1098 | * does **not** protect against the next vblank interrupt racing with either this
|
| 1099 | * function call or the atomic commit operation. A possible sequence could be:
|
| 1100 | *
|
| 1101 | * 1. Driver commits new hardware state into vblank-synchronized registers.
|
| 1102 | * 2. A vblank happens, committing the hardware state. Also the corresponding
|
| 1103 | * vblank interrupt is fired off and fully processed by the interrupt
|
| 1104 | * handler.
|
| 1105 | * 3. The atomic commit operation proceeds to call drm_crtc_arm_vblank_event().
|
| 1106 | * 4. The event is only send out for the next vblank, which is wrong.
|
| 1107 | *
|
| 1108 | * An equivalent race can happen when the driver calls
|
| 1109 | * drm_crtc_arm_vblank_event() before writing out the new hardware state.
|
| 1110 | *
|
| 1111 | * The only way to make this work safely is to prevent the vblank from firing
|
| 1112 | * (and the hardware from committing anything else) until the entire atomic
|
| 1113 | * commit sequence has run to completion. If the hardware does not have such a
|
| 1114 | * feature (e.g. using a "go" bit), then it is unsafe to use this functions.
|
| 1115 | * Instead drivers need to manually send out the event from their interrupt
|
| 1116 | * handler by calling drm_crtc_send_vblank_event() and make sure that there's no
|
| 1117 | * possible race with the hardware committing the atomic update.
|
| 1118 | *
|
| 1119 | * Caller must hold a vblank reference for the event @e acquired by a
|
| 1120 | * drm_crtc_vblank_get(), which will be dropped when the next vblank arrives.
|
| 1121 |
|
| 1122 | void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
|
| 1123 | struct drm_pending_vblank_event *e)
|
| 1124 | {
|
| 1125 | struct drm_device *dev = crtc->dev;
|
| 1126 | unsigned int pipe = drm_crtc_index(crtc);
|
| 1127 |
|
| 1128 | assert_spin_locked(&dev->event_lock);
|
| 1129 |
|
| 1130 | e->pipe = pipe;
|
| 1131 | e->sequence = drm_crtc_accurate_vblank_count(crtc) + 1;
|
| 1132 | list_add_tail(&e->base.link, &dev->vblank_event_list);
|
| 1133 | }
|
| 1134 | EXPORT_SYMBOL(drm_crtc_arm_vblank_event);
|
| 1135 |
|
| 1136 | |
| 1137 | * drm_crtc_send_vblank_event - helper to send vblank event after pageflip
|
| 1138 | * @crtc: the source CRTC of the vblank event
|
| 1139 | * @e: the event to send
|
| 1140 | *
|
| 1141 | * Updates sequence # and timestamp on event for the most recently processed
|
| 1142 | * vblank, and sends it to userspace. Caller must hold event lock.
|
| 1143 | *
|
| 1144 | * See drm_crtc_arm_vblank_event() for a helper which can be used in certain
|
| 1145 | * situation, especially to send out events for atomic commit operations.
|
| 1146 |
|
| 1147 | void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
|
| 1148 | struct drm_pending_vblank_event *e)
|
| 1149 | {
|
| 1150 | struct drm_device *dev = crtc->dev;
|
| 1151 | u64 seq;
|
| 1152 | unsigned int pipe = drm_crtc_index(crtc);
|
| 1153 | ktime_t now;
|
| 1154 |
|
| 1155 | if (drm_dev_has_vblank(dev)) {
|
| 1156 | seq = drm_vblank_count_and_time(dev, pipe, &now);
|
| 1157 | } else {
|
| 1158 | seq = 0;
|
| 1159 |
|
| 1160 | now = ktime_get();
|
| 1161 | }
|
| 1162 | e->pipe = pipe;
|
| 1163 | send_vblank_event(dev, e, seq, now);
|
| 1164 | }
|
| 1165 | EXPORT_SYMBOL(drm_crtc_send_vblank_event);
|
| 1166 |
|
| 1167 | static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
|
| 1168 | {
|
| 1169 | if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
| 1170 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
|
| 1171 |
|
| 1172 | if (drm_WARN_ON(dev, !crtc))
|
| 1173 | return 0;
|
| 1174 |
|
| 1175 | if (crtc->funcs->enable_vblank)
|
| 1176 | return crtc->funcs->enable_vblank(crtc);
|
| 1177 | }
|
| 1178 |
|
| 1179 | return -EINVAL;
|
| 1180 | }
|
| 1181 |
|
| 1182 | static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
|
| 1183 | {
|
| 1184 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 1185 | int ret = 0;
|
| 1186 |
|
| 1187 | assert_spin_locked(&dev->vbl_lock);
|
| 1188 |
|
| 1189 | spin_lock(&dev->vblank_time_lock);
|
| 1190 |
|
| 1191 | if (!vblank->enabled) {
|
| 1192 | |
| 1193 | * Enable vblank irqs under vblank_time_lock protection.
|
| 1194 | * All vblank count & timestamp updates are held off
|
| 1195 | * until we are done reinitializing master counter and
|
| 1196 | * timestamps. Filtercode in drm_handle_vblank() will
|
| 1197 | * prevent double-accounting of same vblank interval.
|
| 1198 |
|
| 1199 | ret = __enable_vblank(dev, pipe);
|
| 1200 | drm_dbg_core(dev, "enabling vblank on crtc %u, ret: %d\n",
|
| 1201 | pipe, ret);
|
| 1202 | if (ret) {
|
| 1203 | atomic_dec(&vblank->refcount);
|
| 1204 | } else {
|
| 1205 | drm_update_vblank_count(dev, pipe, 0);
|
| 1206 | |
| 1207 | * need to ensure that the compiler emits the write
|
| 1208 | * to mark the vblank as enabled after the call
|
| 1209 | * to drm_update_vblank_count().
|
| 1210 |
|
| 1211 | WRITE_ONCE(vblank->enabled, true);
|
| 1212 | }
|
| 1213 | }
|
| 1214 |
|
| 1215 | spin_unlock(&dev->vblank_time_lock);
|
| 1216 |
|
| 1217 | return ret;
|
| 1218 | }
|
| 1219 |
|
| 1220 | int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
|
| 1221 | {
|
| 1222 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 1223 | unsigned long irqflags;
|
| 1224 | int ret = 0;
|
| 1225 |
|
| 1226 | if (!drm_dev_has_vblank(dev))
|
| 1227 | return -EINVAL;
|
| 1228 |
|
| 1229 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 1230 | return -EINVAL;
|
| 1231 |
|
| 1232 | spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
| 1233 |
|
| 1234 | if (atomic_add_return(1, &vblank->refcount) == 1) {
|
| 1235 | ret = drm_vblank_enable(dev, pipe);
|
| 1236 | } else {
|
| 1237 | if (!vblank->enabled) {
|
| 1238 | atomic_dec(&vblank->refcount);
|
| 1239 | ret = -EINVAL;
|
| 1240 | }
|
| 1241 | }
|
| 1242 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
| 1243 |
|
| 1244 | return ret;
|
| 1245 | }
|
| 1246 |
|
| 1247 | |
| 1248 | * drm_crtc_vblank_get - get a reference count on vblank events
|
| 1249 | * @crtc: which CRTC to own
|
| 1250 | *
|
| 1251 | * Acquire a reference count on vblank events to avoid having them disabled
|
| 1252 | * while in use.
|
| 1253 | *
|
| 1254 | * Returns:
|
| 1255 | * Zero on success or a negative error code on failure.
|
| 1256 |
|
| 1257 | int drm_crtc_vblank_get(struct drm_crtc *crtc)
|
| 1258 | {
|
| 1259 | return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
|
| 1260 | }
|
| 1261 | EXPORT_SYMBOL(drm_crtc_vblank_get);
|
| 1262 |
|
| 1263 | void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
|
| 1264 | {
|
| 1265 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 1266 | int vblank_offdelay = vblank->config.offdelay_ms;
|
| 1267 |
|
| 1268 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 1269 | return;
|
| 1270 |
|
| 1271 | if (drm_WARN_ON(dev, atomic_read(&vblank->refcount) == 0))
|
| 1272 | return;
|
| 1273 |
|
| 1274 |
|
| 1275 | if (atomic_dec_and_test(&vblank->refcount)) {
|
| 1276 | if (!vblank_offdelay)
|
| 1277 | return;
|
| 1278 | else if (vblank_offdelay < 0)
|
| 1279 | vblank_disable_fn(&vblank->disable_timer);
|
| 1280 | else if (!vblank->config.disable_immediate)
|
| 1281 | mod_timer(&vblank->disable_timer,
|
| 1282 | jiffies + ((vblank_offdelay * HZ) / 1000));
|
| 1283 | }
|
| 1284 | }
|
| 1285 |
|
| 1286 | |
| 1287 | * drm_crtc_vblank_put - give up ownership of vblank events
|
| 1288 | * @crtc: which counter to give up
|
| 1289 | *
|
| 1290 | * Release ownership of a given vblank counter, turning off interrupts
|
| 1291 | * if possible. Disable interrupts after &drm_vblank_crtc_config.offdelay_ms
|
| 1292 | * milliseconds.
|
| 1293 |
|
| 1294 | void drm_crtc_vblank_put(struct drm_crtc *crtc)
|
| 1295 | {
|
| 1296 | drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
|
| 1297 | }
|
| 1298 | EXPORT_SYMBOL(drm_crtc_vblank_put);
|
| 1299 |
|
| 1300 | |
| 1301 | * drm_crtc_wait_one_vblank - wait for one vblank
|
| 1302 | * @crtc: DRM crtc
|
| 1303 | *
|
| 1304 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
|
| 1305 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
|
| 1306 | * due to lack of driver support or because the crtc is off.
|
| 1307 | *
|
| 1308 | * Returns: 0 on success, negative error on failures.
|
| 1309 |
|
| 1310 | int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
|
| 1311 | {
|
| 1312 | struct drm_device *dev = crtc->dev;
|
| 1313 | int pipe = drm_crtc_index(crtc);
|
| 1314 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 1315 | int ret;
|
| 1316 | u64 last;
|
| 1317 |
|
| 1318 | ret = drm_vblank_get(dev, pipe);
|
| 1319 | if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
|
| 1320 | pipe, ret))
|
| 1321 | return ret;
|
| 1322 |
|
| 1323 | last = drm_vblank_count(dev, pipe);
|
| 1324 |
|
| 1325 | ret = wait_event_timeout(vblank->queue,
|
| 1326 | last != drm_vblank_count(dev, pipe),
|
| 1327 | msecs_to_jiffies(1000));
|
| 1328 |
|
| 1329 | drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
|
| 1330 |
|
| 1331 | drm_vblank_put(dev, pipe);
|
| 1332 |
|
| 1333 | return ret ? 0 : -ETIMEDOUT;
|
| 1334 | }
|
| 1335 | EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
|
| 1336 |
|
| 1337 | |
| 1338 | * drm_crtc_vblank_off - disable vblank events on a CRTC
|
| 1339 | * @crtc: CRTC in question
|
| 1340 | *
|
| 1341 | * Drivers can use this function to shut down the vblank interrupt handling when
|
| 1342 | * disabling a crtc. This function ensures that the latest vblank frame count is
|
| 1343 | * stored so that drm_vblank_on can restore it again.
|
| 1344 | *
|
| 1345 | * Drivers must use this function when the hardware vblank counter can get
|
| 1346 | * reset, e.g. when suspending or disabling the @crtc in general.
|
| 1347 |
|
| 1348 | void drm_crtc_vblank_off(struct drm_crtc *crtc)
|
| 1349 | {
|
| 1350 | struct drm_device *dev = crtc->dev;
|
| 1351 | unsigned int pipe = drm_crtc_index(crtc);
|
| 1352 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 1353 | struct drm_pending_vblank_event *e, *t;
|
| 1354 | ktime_t now;
|
| 1355 | u64 seq;
|
| 1356 |
|
| 1357 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 1358 | return;
|
| 1359 |
|
| 1360 | |
| 1361 | * Grab event_lock early to prevent vblank work from being scheduled
|
| 1362 | * while we're in the middle of shutting down vblank interrupts
|
| 1363 |
|
| 1364 | spin_lock_irq(&dev->event_lock);
|
| 1365 |
|
| 1366 | spin_lock(&dev->vbl_lock);
|
| 1367 | drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
|
| 1368 | pipe, vblank->enabled, vblank->inmodeset);
|
| 1369 |
|
| 1370 | |
| 1371 | * drm_crtc_vblank_on().
|
| 1372 | if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset)
|
| 1373 | drm_vblank_disable_and_save(dev, pipe);
|
| 1374 |
|
| 1375 | wake_up(&vblank->queue);
|
| 1376 |
|
| 1377 | |
| 1378 | * Prevent subsequent drm_vblank_get() from re-enabling
|
| 1379 | * the vblank interrupt by bumping the refcount.
|
| 1380 |
|
| 1381 | if (!vblank->inmodeset) {
|
| 1382 | atomic_inc(&vblank->refcount);
|
| 1383 | vblank->inmodeset = 1;
|
| 1384 | }
|
| 1385 | spin_unlock(&dev->vbl_lock);
|
| 1386 |
|
| 1387 |
|
| 1388 | seq = drm_vblank_count_and_time(dev, pipe, &now);
|
| 1389 |
|
| 1390 | list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
|
| 1391 | if (e->pipe != pipe)
|
| 1392 | continue;
|
| 1393 | drm_dbg_core(dev, "Sending premature vblank event on disable: "
|
| 1394 | "wanted %llu, current %llu\n",
|
| 1395 | e->sequence, seq);
|
| 1396 | list_del(&e->base.link);
|
| 1397 | drm_vblank_put(dev, pipe);
|
| 1398 | send_vblank_event(dev, e, seq, now);
|
| 1399 | }
|
| 1400 |
|
| 1401 |
|
| 1402 | drm_vblank_cancel_pending_works(vblank);
|
| 1403 |
|
| 1404 | spin_unlock_irq(&dev->event_lock);
|
| 1405 |
|
| 1406 | |
| 1407 | * calling drm_calc_timestamping_constants().
|
| 1408 | vblank->hwmode.crtc_clock = 0;
|
| 1409 |
|
| 1410 |
|
| 1411 | drm_vblank_flush_worker(vblank);
|
| 1412 | }
|
| 1413 | EXPORT_SYMBOL(drm_crtc_vblank_off);
|
| 1414 |
|
| 1415 | |
| 1416 | * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
|
| 1417 | * @crtc: CRTC in question
|
| 1418 | *
|
| 1419 | * Drivers can use this function to reset the vblank state to off at load time.
|
| 1420 | * Drivers should use this together with the drm_crtc_vblank_off() and
|
| 1421 | * drm_crtc_vblank_on() functions. The difference compared to
|
| 1422 | * drm_crtc_vblank_off() is that this function doesn't save the vblank counter
|
| 1423 | * and hence doesn't need to call any driver hooks.
|
| 1424 | *
|
| 1425 | * This is useful for recovering driver state e.g. on driver load, or on resume.
|
| 1426 |
|
| 1427 | void drm_crtc_vblank_reset(struct drm_crtc *crtc)
|
| 1428 | {
|
| 1429 | struct drm_device *dev = crtc->dev;
|
| 1430 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 1431 |
|
| 1432 | spin_lock_irq(&dev->vbl_lock);
|
| 1433 | |
| 1434 | * Prevent subsequent drm_vblank_get() from enabling the vblank
|
| 1435 | * interrupt by bumping the refcount.
|
| 1436 |
|
| 1437 | if (!vblank->inmodeset) {
|
| 1438 | atomic_inc(&vblank->refcount);
|
| 1439 | vblank->inmodeset = 1;
|
| 1440 | }
|
| 1441 | spin_unlock_irq(&dev->vbl_lock);
|
| 1442 |
|
| 1443 | drm_WARN_ON(dev, !list_empty(&dev->vblank_event_list));
|
| 1444 | drm_WARN_ON(dev, !list_empty(&vblank->pending_work));
|
| 1445 | }
|
| 1446 | EXPORT_SYMBOL(drm_crtc_vblank_reset);
|
| 1447 |
|
| 1448 | |
| 1449 | * drm_crtc_set_max_vblank_count - configure the hw max vblank counter value
|
| 1450 | * @crtc: CRTC in question
|
| 1451 | * @max_vblank_count: max hardware vblank counter value
|
| 1452 | *
|
| 1453 | * Update the maximum hardware vblank counter value for @crtc
|
| 1454 | * at runtime. Useful for hardware where the operation of the
|
| 1455 | * hardware vblank counter depends on the currently active
|
| 1456 | * display configuration.
|
| 1457 | *
|
| 1458 | * For example, if the hardware vblank counter does not work
|
| 1459 | * when a specific connector is active the maximum can be set
|
| 1460 | * to zero. And when that specific connector isn't active the
|
| 1461 | * maximum can again be set to the appropriate non-zero value.
|
| 1462 | *
|
| 1463 | * If used, must be called before drm_vblank_on().
|
| 1464 |
|
| 1465 | void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
|
| 1466 | u32 max_vblank_count)
|
| 1467 | {
|
| 1468 | struct drm_device *dev = crtc->dev;
|
| 1469 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 1470 |
|
| 1471 | drm_WARN_ON(dev, dev->max_vblank_count);
|
| 1472 | drm_WARN_ON(dev, !READ_ONCE(vblank->inmodeset));
|
| 1473 |
|
| 1474 | vblank->max_vblank_count = max_vblank_count;
|
| 1475 | }
|
| 1476 | EXPORT_SYMBOL(drm_crtc_set_max_vblank_count);
|
| 1477 |
|
| 1478 | |
| 1479 | * drm_crtc_vblank_on_config - enable vblank events on a CRTC with custom
|
| 1480 | * configuration options
|
| 1481 | * @crtc: CRTC in question
|
| 1482 | * @config: Vblank configuration value
|
| 1483 | *
|
| 1484 | * See drm_crtc_vblank_on(). In addition, this function allows you to provide a
|
| 1485 | * custom vblank configuration for a given CRTC.
|
| 1486 | *
|
| 1487 | * Note that @config is copied, the pointer does not need to stay valid beyond
|
| 1488 | * this function call. For details of the parameters see
|
| 1489 | * struct drm_vblank_crtc_config.
|
| 1490 |
|
| 1491 | void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
|
| 1492 | const struct drm_vblank_crtc_config *config)
|
| 1493 | {
|
| 1494 | struct drm_device *dev = crtc->dev;
|
| 1495 | unsigned int pipe = drm_crtc_index(crtc);
|
| 1496 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 1497 |
|
| 1498 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 1499 | return;
|
| 1500 |
|
| 1501 | spin_lock_irq(&dev->vbl_lock);
|
| 1502 | drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
|
| 1503 | pipe, vblank->enabled, vblank->inmodeset);
|
| 1504 |
|
| 1505 | vblank->config = *config;
|
| 1506 |
|
| 1507 |
|
| 1508 | if (vblank->inmodeset) {
|
| 1509 | atomic_dec(&vblank->refcount);
|
| 1510 | vblank->inmodeset = 0;
|
| 1511 | }
|
| 1512 |
|
| 1513 | drm_reset_vblank_timestamp(dev, pipe);
|
| 1514 |
|
| 1515 | |
| 1516 | * re-enable interrupts if there are users left, or the
|
| 1517 | * user wishes vblank interrupts to be enabled all the time.
|
| 1518 |
|
| 1519 | if (atomic_read(&vblank->refcount) != 0 || !vblank->config.offdelay_ms)
|
| 1520 | drm_WARN_ON(dev, drm_vblank_enable(dev, pipe));
|
| 1521 | spin_unlock_irq(&dev->vbl_lock);
|
| 1522 | }
|
| 1523 | EXPORT_SYMBOL(drm_crtc_vblank_on_config);
|
| 1524 |
|
| 1525 | |
| 1526 | * drm_crtc_vblank_on - enable vblank events on a CRTC
|
| 1527 | * @crtc: CRTC in question
|
| 1528 | *
|
| 1529 | * This functions restores the vblank interrupt state captured with
|
| 1530 | * drm_crtc_vblank_off() again and is generally called when enabling @crtc. Note
|
| 1531 | * that calls to drm_crtc_vblank_on() and drm_crtc_vblank_off() can be
|
| 1532 | * unbalanced and so can also be unconditionally called in driver load code to
|
| 1533 | * reflect the current hardware state of the crtc.
|
| 1534 | *
|
| 1535 | * Note that unlike in drm_crtc_vblank_on_config(), default values are used.
|
| 1536 |
|
| 1537 | void drm_crtc_vblank_on(struct drm_crtc *crtc)
|
| 1538 | {
|
| 1539 | const struct drm_vblank_crtc_config config = {
|
| 1540 | .offdelay_ms = drm_vblank_offdelay,
|
| 1541 | .disable_immediate = crtc->dev->vblank_disable_immediate
|
| 1542 | };
|
| 1543 |
|
| 1544 | drm_crtc_vblank_on_config(crtc, &config);
|
| 1545 | }
|
| 1546 | EXPORT_SYMBOL(drm_crtc_vblank_on);
|
| 1547 |
|
| 1548 | static void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
|
| 1549 | {
|
| 1550 | ktime_t t_vblank;
|
| 1551 | struct drm_vblank_crtc *vblank;
|
| 1552 | int framedur_ns;
|
| 1553 | u64 diff_ns;
|
| 1554 | u32 cur_vblank, diff = 1;
|
| 1555 | u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
|
| 1556 |
|
| 1557 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 1558 | return;
|
| 1559 |
|
| 1560 | assert_spin_locked(&dev->vbl_lock);
|
| 1561 | assert_spin_locked(&dev->vblank_time_lock);
|
| 1562 |
|
| 1563 | vblank = drm_vblank_crtc(dev, pipe);
|
| 1564 | drm_WARN_ONCE(dev,
|
| 1565 | drm_debug_enabled(DRM_UT_VBL) && !vblank->framedur_ns,
|
| 1566 | "Cannot compute missed vblanks without frame duration\n");
|
| 1567 | framedur_ns = vblank->framedur_ns;
|
| 1568 |
|
| 1569 | get_vblank_counter_and_timestamp(dev, pipe, &cur_vblank,
|
| 1570 | &t_vblank, false);
|
| 1571 |
|
| 1572 | diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
|
| 1573 | if (framedur_ns)
|
| 1574 | diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
|
| 1575 |
|
| 1576 |
|
| 1577 | drm_dbg_vbl(dev,
|
| 1578 | "missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n",
|
| 1579 | diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
|
| 1580 | vblank->last = (cur_vblank - diff) & max_vblank_count;
|
| 1581 | }
|
| 1582 |
|
| 1583 | |
| 1584 | * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
|
| 1585 | * @crtc: CRTC in question
|
| 1586 | *
|
| 1587 | * Power manamement features can cause frame counter resets between vblank
|
| 1588 | * disable and enable. Drivers can use this function in their
|
| 1589 | * &drm_crtc_funcs.enable_vblank implementation to estimate missed vblanks since
|
| 1590 | * the last &drm_crtc_funcs.disable_vblank using timestamps and update the
|
| 1591 | * vblank counter.
|
| 1592 | *
|
| 1593 | * Note that drivers must have race-free high-precision timestamping support,
|
| 1594 | * i.e. &drm_crtc_funcs.get_vblank_timestamp must be hooked up and
|
| 1595 | * &drm_vblank_crtc_config.disable_immediate must be set to indicate the
|
| 1596 | * time-stamping functions are race-free against vblank hardware counter
|
| 1597 | * increments.
|
| 1598 |
|
| 1599 | void drm_crtc_vblank_restore(struct drm_crtc *crtc)
|
| 1600 | {
|
| 1601 | struct drm_device *dev = crtc->dev;
|
| 1602 | unsigned int pipe = drm_crtc_index(crtc);
|
| 1603 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 1604 |
|
| 1605 | drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
|
| 1606 | drm_WARN_ON_ONCE(dev, vblank->inmodeset);
|
| 1607 | drm_WARN_ON_ONCE(dev, !vblank->config.disable_immediate);
|
| 1608 |
|
| 1609 | drm_vblank_restore(dev, pipe);
|
| 1610 | }
|
| 1611 | EXPORT_SYMBOL(drm_crtc_vblank_restore);
|
| 1612 |
|
| 1613 | static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
|
| 1614 | u64 req_seq,
|
| 1615 | union drm_wait_vblank *vblwait,
|
| 1616 | struct drm_file *file_priv)
|
| 1617 | {
|
| 1618 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 1619 | struct drm_pending_vblank_event *e;
|
| 1620 | ktime_t now;
|
| 1621 | u64 seq;
|
| 1622 | int ret;
|
| 1623 |
|
| 1624 | e = kzalloc_obj(*e);
|
| 1625 | if (e == NULL) {
|
| 1626 | ret = -ENOMEM;
|
| 1627 | goto err_put;
|
| 1628 | }
|
| 1629 |
|
| 1630 | e->pipe = pipe;
|
| 1631 | e->event.base.type = DRM_EVENT_VBLANK;
|
| 1632 | e->event.base.length = sizeof(e->event.vbl);
|
| 1633 | e->event.vbl.user_data = vblwait->request.signal;
|
| 1634 | e->event.vbl.crtc_id = 0;
|
| 1635 | if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
| 1636 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
|
| 1637 |
|
| 1638 | if (crtc)
|
| 1639 | e->event.vbl.crtc_id = crtc->base.id;
|
| 1640 | }
|
| 1641 |
|
| 1642 | spin_lock_irq(&dev->event_lock);
|
| 1643 |
|
| 1644 | |
| 1645 | * drm_crtc_vblank_off() might have been called after we called
|
| 1646 | * drm_vblank_get(). drm_crtc_vblank_off() holds event_lock around the
|
| 1647 | * vblank disable, so no need for further locking. The reference from
|
| 1648 | * drm_vblank_get() protects against vblank disable from another source.
|
| 1649 |
|
| 1650 | if (!READ_ONCE(vblank->enabled)) {
|
| 1651 | ret = -EINVAL;
|
| 1652 | goto err_unlock;
|
| 1653 | }
|
| 1654 |
|
| 1655 | ret = drm_event_reserve_init_locked(dev, file_priv, &e->base,
|
| 1656 | &e->event.base);
|
| 1657 |
|
| 1658 | if (ret)
|
| 1659 | goto err_unlock;
|
| 1660 |
|
| 1661 | seq = drm_vblank_count_and_time(dev, pipe, &now);
|
| 1662 |
|
| 1663 | drm_dbg_core(dev, "event on vblank count %llu, current %llu, crtc %u\n",
|
| 1664 | req_seq, seq, pipe);
|
| 1665 |
|
| 1666 | trace_drm_vblank_event_queued(file_priv, pipe, req_seq);
|
| 1667 |
|
| 1668 | e->sequence = req_seq;
|
| 1669 | if (drm_vblank_passed(seq, req_seq)) {
|
| 1670 | drm_vblank_put(dev, pipe);
|
| 1671 | send_vblank_event(dev, e, seq, now);
|
| 1672 | vblwait->reply.sequence = seq;
|
| 1673 | } else {
|
| 1674 |
|
| 1675 | list_add_tail(&e->base.link, &dev->vblank_event_list);
|
| 1676 | vblwait->reply.sequence = req_seq;
|
| 1677 | }
|
| 1678 |
|
| 1679 | spin_unlock_irq(&dev->event_lock);
|
| 1680 |
|
| 1681 | return 0;
|
| 1682 |
|
| 1683 | err_unlock:
|
| 1684 | spin_unlock_irq(&dev->event_lock);
|
| 1685 | kfree(e);
|
| 1686 | err_put:
|
| 1687 | drm_vblank_put(dev, pipe);
|
| 1688 | return ret;
|
| 1689 | }
|
| 1690 |
|
| 1691 | static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
|
| 1692 | {
|
| 1693 | if (vblwait->request.sequence)
|
| 1694 | return false;
|
| 1695 |
|
| 1696 | return _DRM_VBLANK_RELATIVE ==
|
| 1697 | (vblwait->request.type & (_DRM_VBLANK_TYPES_MASK |
|
| 1698 | _DRM_VBLANK_EVENT |
|
| 1699 | _DRM_VBLANK_NEXTONMISS));
|
| 1700 | }
|
| 1701 |
|
| 1702 | |
| 1703 | * Widen a 32-bit param to 64-bits.
|
| 1704 | *
|
| 1705 | * \param narrow 32-bit value (missing upper 32 bits)
|
| 1706 | * \param near 64-bit value that should be 'close' to near
|
| 1707 | *
|
| 1708 | * This function returns a 64-bit value using the lower 32-bits from
|
| 1709 | * 'narrow' and constructing the upper 32-bits so that the result is
|
| 1710 | * as close as possible to 'near'.
|
| 1711 |
|
| 1712 |
|
| 1713 | static u64 widen_32_to_64(u32 narrow, u64 near)
|
| 1714 | {
|
| 1715 | return near + (s32) (narrow - near);
|
| 1716 | }
|
| 1717 |
|
| 1718 | static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
|
| 1719 | struct drm_wait_vblank_reply *reply)
|
| 1720 | {
|
| 1721 | ktime_t now;
|
| 1722 | struct timespec64 ts;
|
| 1723 |
|
| 1724 | |
| 1725 | * drm_wait_vblank_reply is a UAPI structure that uses 'long'
|
| 1726 | * to store the seconds. This is safe as we always use monotonic
|
| 1727 | * timestamps since linux-4.15.
|
| 1728 |
|
| 1729 | reply->sequence = drm_vblank_count_and_time(dev, pipe, &now);
|
| 1730 | ts = ktime_to_timespec64(now);
|
| 1731 | reply->tval_sec = (u32)ts.tv_sec;
|
| 1732 | reply->tval_usec = ts.tv_nsec / 1000;
|
| 1733 | }
|
| 1734 |
|
| 1735 | static bool drm_wait_vblank_supported(struct drm_device *dev)
|
| 1736 | {
|
| 1737 | return drm_dev_has_vblank(dev);
|
| 1738 | }
|
| 1739 |
|
| 1740 | int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
|
| 1741 | struct drm_file *file_priv)
|
| 1742 | {
|
| 1743 | struct drm_crtc *crtc;
|
| 1744 | struct drm_vblank_crtc *vblank;
|
| 1745 | union drm_wait_vblank *vblwait = data;
|
| 1746 | int ret;
|
| 1747 | u64 req_seq, seq;
|
| 1748 | unsigned int pipe_index;
|
| 1749 | unsigned int flags, pipe, high_pipe;
|
| 1750 |
|
| 1751 | if (!drm_wait_vblank_supported(dev))
|
| 1752 | return -EOPNOTSUPP;
|
| 1753 |
|
| 1754 | if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
|
| 1755 | return -EINVAL;
|
| 1756 |
|
| 1757 | if (vblwait->request.type &
|
| 1758 | ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
|
| 1759 | _DRM_VBLANK_HIGH_CRTC_MASK)) {
|
| 1760 | drm_dbg_core(dev,
|
| 1761 | "Unsupported type value 0x%x, supported mask 0x%x\n",
|
| 1762 | vblwait->request.type,
|
| 1763 | (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
|
| 1764 | _DRM_VBLANK_HIGH_CRTC_MASK));
|
| 1765 | return -EINVAL;
|
| 1766 | }
|
| 1767 |
|
| 1768 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
|
| 1769 | high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
|
| 1770 | if (high_pipe)
|
| 1771 | pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
|
| 1772 | else
|
| 1773 | pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
|
| 1774 |
|
| 1775 |
|
| 1776 | if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
| 1777 | pipe = 0;
|
| 1778 | drm_for_each_crtc(crtc, dev) {
|
| 1779 | if (drm_lease_held(file_priv, crtc->base.id)) {
|
| 1780 | if (pipe_index == 0)
|
| 1781 | break;
|
| 1782 | pipe_index--;
|
| 1783 | }
|
| 1784 | pipe++;
|
| 1785 | }
|
| 1786 | } else {
|
| 1787 | pipe = pipe_index;
|
| 1788 | }
|
| 1789 |
|
| 1790 | if (pipe >= dev->num_crtcs)
|
| 1791 | return -EINVAL;
|
| 1792 |
|
| 1793 | vblank = drm_vblank_crtc(dev, pipe);
|
| 1794 |
|
| 1795 | |
| 1796 | * queries to return the cached timestamp of the last vblank.
|
| 1797 |
|
| 1798 | if (vblank->config.disable_immediate &&
|
| 1799 | drm_wait_vblank_is_query(vblwait) &&
|
| 1800 | READ_ONCE(vblank->enabled)) {
|
| 1801 | drm_wait_vblank_reply(dev, pipe, &vblwait->reply);
|
| 1802 | return 0;
|
| 1803 | }
|
| 1804 |
|
| 1805 | ret = drm_vblank_get(dev, pipe);
|
| 1806 | if (ret) {
|
| 1807 | drm_dbg_core(dev,
|
| 1808 | "crtc %d failed to acquire vblank counter, %d\n",
|
| 1809 | pipe, ret);
|
| 1810 | return ret;
|
| 1811 | }
|
| 1812 | seq = drm_vblank_count(dev, pipe);
|
| 1813 |
|
| 1814 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
|
| 1815 | case _DRM_VBLANK_RELATIVE:
|
| 1816 | req_seq = seq + vblwait->request.sequence;
|
| 1817 | vblwait->request.sequence = req_seq;
|
| 1818 | vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
|
| 1819 | break;
|
| 1820 | case _DRM_VBLANK_ABSOLUTE:
|
| 1821 | req_seq = widen_32_to_64(vblwait->request.sequence, seq);
|
| 1822 | break;
|
| 1823 | default:
|
| 1824 | ret = -EINVAL;
|
| 1825 | goto done;
|
| 1826 | }
|
| 1827 |
|
| 1828 | if ((flags & _DRM_VBLANK_NEXTONMISS) &&
|
| 1829 | drm_vblank_passed(seq, req_seq)) {
|
| 1830 | req_seq = seq + 1;
|
| 1831 | vblwait->request.type &= ~_DRM_VBLANK_NEXTONMISS;
|
| 1832 | vblwait->request.sequence = req_seq;
|
| 1833 | }
|
| 1834 |
|
| 1835 | if (flags & _DRM_VBLANK_EVENT) {
|
| 1836 | |
| 1837 | * drm_vblank_put will be called asynchronously
|
| 1838 |
|
| 1839 | return drm_queue_vblank_event(dev, pipe, req_seq, vblwait, file_priv);
|
| 1840 | }
|
| 1841 |
|
| 1842 | if (req_seq != seq) {
|
| 1843 | int wait;
|
| 1844 |
|
| 1845 | drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
|
| 1846 | req_seq, pipe);
|
| 1847 | wait = wait_event_interruptible_timeout(vblank->queue,
|
| 1848 | drm_vblank_passed(drm_vblank_count(dev, pipe), req_seq) ||
|
| 1849 | !READ_ONCE(vblank->enabled),
|
| 1850 | msecs_to_jiffies(3000));
|
| 1851 |
|
| 1852 | switch (wait) {
|
| 1853 | case 0:
|
| 1854 |
|
| 1855 | ret = -EBUSY;
|
| 1856 | break;
|
| 1857 | case -ERESTARTSYS:
|
| 1858 |
|
| 1859 | ret = -EINTR;
|
| 1860 | break;
|
| 1861 | default:
|
| 1862 | ret = 0;
|
| 1863 | break;
|
| 1864 | }
|
| 1865 | }
|
| 1866 |
|
| 1867 | if (ret != -EINTR) {
|
| 1868 | drm_wait_vblank_reply(dev, pipe, &vblwait->reply);
|
| 1869 |
|
| 1870 | drm_dbg_core(dev, "crtc %d returning %u to client\n",
|
| 1871 | pipe, vblwait->reply.sequence);
|
| 1872 | } else {
|
| 1873 | drm_dbg_core(dev, "crtc %d vblank wait interrupted by signal\n",
|
| 1874 | pipe);
|
| 1875 | }
|
| 1876 |
|
| 1877 | done:
|
| 1878 | drm_vblank_put(dev, pipe);
|
| 1879 | return ret;
|
| 1880 | }
|
| 1881 |
|
| 1882 | static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
|
| 1883 | {
|
| 1884 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
|
| 1885 | bool high_prec = false;
|
| 1886 | struct drm_pending_vblank_event *e, *t;
|
| 1887 | ktime_t now;
|
| 1888 | u64 seq;
|
| 1889 |
|
| 1890 | assert_spin_locked(&dev->event_lock);
|
| 1891 |
|
| 1892 | seq = drm_vblank_count_and_time(dev, pipe, &now);
|
| 1893 |
|
| 1894 | list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
|
| 1895 | if (e->pipe != pipe)
|
| 1896 | continue;
|
| 1897 | if (!drm_vblank_passed(seq, e->sequence))
|
| 1898 | continue;
|
| 1899 |
|
| 1900 | drm_dbg_core(dev, "vblank event on %llu, current %llu\n",
|
| 1901 | e->sequence, seq);
|
| 1902 |
|
| 1903 | list_del(&e->base.link);
|
| 1904 | drm_vblank_put(dev, pipe);
|
| 1905 | send_vblank_event(dev, e, seq, now);
|
| 1906 | }
|
| 1907 |
|
| 1908 | if (crtc && crtc->funcs->get_vblank_timestamp)
|
| 1909 | high_prec = true;
|
| 1910 |
|
| 1911 | trace_drm_vblank_event(pipe, seq, now, high_prec);
|
| 1912 | }
|
| 1913 |
|
| 1914 | |
| 1915 | * drm_handle_vblank - handle a vblank event
|
| 1916 | * @dev: DRM device
|
| 1917 | * @pipe: index of CRTC where this event occurred
|
| 1918 | *
|
| 1919 | * Drivers should call this routine in their vblank interrupt handlers to
|
| 1920 | * update the vblank counter and send any signals that may be pending.
|
| 1921 | *
|
| 1922 | * This is the legacy version of drm_crtc_handle_vblank().
|
| 1923 |
|
| 1924 | bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
|
| 1925 | {
|
| 1926 | struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
|
| 1927 | unsigned long irqflags;
|
| 1928 | bool disable_irq;
|
| 1929 |
|
| 1930 | if (drm_WARN_ON_ONCE(dev, !drm_dev_has_vblank(dev)))
|
| 1931 | return false;
|
| 1932 |
|
| 1933 | if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
|
| 1934 | return false;
|
| 1935 |
|
| 1936 | spin_lock_irqsave(&dev->event_lock, irqflags);
|
| 1937 |
|
| 1938 | |
| 1939 | * vblank enable/disable, as this would cause inconsistent
|
| 1940 | * or corrupted timestamps and vblank counts.
|
| 1941 |
|
| 1942 | spin_lock(&dev->vblank_time_lock);
|
| 1943 |
|
| 1944 |
|
| 1945 | if (!vblank->enabled) {
|
| 1946 | spin_unlock(&dev->vblank_time_lock);
|
| 1947 | spin_unlock_irqrestore(&dev->event_lock, irqflags);
|
| 1948 | return false;
|
| 1949 | }
|
| 1950 |
|
| 1951 | drm_update_vblank_count(dev, pipe, true);
|
| 1952 |
|
| 1953 | spin_unlock(&dev->vblank_time_lock);
|
| 1954 |
|
| 1955 | wake_up(&vblank->queue);
|
| 1956 |
|
| 1957 | |
| 1958 | * we finish processing the following vblank after all events have
|
| 1959 | * been signaled. The disable has to be last (after
|
| 1960 | * drm_handle_vblank_events) so that the timestamp is always accurate.
|
| 1961 |
|
| 1962 | disable_irq = (vblank->config.disable_immediate &&
|
| 1963 | vblank->config.offdelay_ms > 0 &&
|
| 1964 | !atomic_read(&vblank->refcount));
|
| 1965 |
|
| 1966 | drm_handle_vblank_events(dev, pipe);
|
| 1967 | drm_handle_vblank_works(vblank);
|
| 1968 |
|
| 1969 | spin_unlock_irqrestore(&dev->event_lock, irqflags);
|
| 1970 |
|
| 1971 | if (disable_irq)
|
| 1972 | vblank_disable_fn(&vblank->disable_timer);
|
| 1973 |
|
| 1974 | return true;
|
| 1975 | }
|
| 1976 | EXPORT_SYMBOL(drm_handle_vblank);
|
| 1977 |
|
| 1978 | |
| 1979 | * drm_crtc_handle_vblank - handle a vblank event
|
| 1980 | * @crtc: where this event occurred
|
| 1981 | *
|
| 1982 | * Drivers should call this routine in their vblank interrupt handlers to
|
| 1983 | * update the vblank counter and send any signals that may be pending.
|
| 1984 | *
|
| 1985 | * This is the native KMS version of drm_handle_vblank().
|
| 1986 | *
|
| 1987 | * Note that for a given vblank counter value drm_crtc_handle_vblank()
|
| 1988 | * and drm_crtc_vblank_count() or drm_crtc_vblank_count_and_time()
|
| 1989 | * provide a barrier: Any writes done before calling
|
| 1990 | * drm_crtc_handle_vblank() will be visible to callers of the later
|
| 1991 | * functions, if the vblank count is the same or a later one.
|
| 1992 | *
|
| 1993 | * See also &drm_vblank_crtc.count.
|
| 1994 | *
|
| 1995 | * Returns:
|
| 1996 | * True if the event was successfully handled, false on failure.
|
| 1997 |
|
| 1998 | bool drm_crtc_handle_vblank(struct drm_crtc *crtc)
|
| 1999 | {
|
| 2000 | return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
|
| 2001 | }
|
| 2002 | EXPORT_SYMBOL(drm_crtc_handle_vblank);
|
| 2003 |
|
| 2004 | |
| 2005 | * Get crtc VBLANK count.
|
| 2006 | *
|
| 2007 | * \param dev DRM device
|
| 2008 | * \param data user argument, pointing to a drm_crtc_get_sequence structure.
|
| 2009 | * \param file_priv drm file private for the user's open file descriptor
|
| 2010 |
|
| 2011 |
|
| 2012 | int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
|
| 2013 | struct drm_file *file_priv)
|
| 2014 | {
|
| 2015 | struct drm_crtc *crtc;
|
| 2016 | struct drm_vblank_crtc *vblank;
|
| 2017 | int pipe;
|
| 2018 | struct drm_crtc_get_sequence *get_seq = data;
|
| 2019 | ktime_t now;
|
| 2020 | bool vblank_enabled;
|
| 2021 | int ret;
|
| 2022 |
|
| 2023 | if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
| 2024 | return -EOPNOTSUPP;
|
| 2025 |
|
| 2026 | if (!drm_dev_has_vblank(dev))
|
| 2027 | return -EOPNOTSUPP;
|
| 2028 |
|
| 2029 | crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id);
|
| 2030 | if (!crtc)
|
| 2031 | return -ENOENT;
|
| 2032 |
|
| 2033 | pipe = drm_crtc_index(crtc);
|
| 2034 |
|
| 2035 | vblank = drm_crtc_vblank_crtc(crtc);
|
| 2036 | vblank_enabled = READ_ONCE(vblank->config.disable_immediate) &&
|
| 2037 | READ_ONCE(vblank->enabled);
|
| 2038 |
|
| 2039 | if (!vblank_enabled) {
|
| 2040 | ret = drm_crtc_vblank_get(crtc);
|
| 2041 | if (ret) {
|
| 2042 | drm_dbg_core(dev,
|
| 2043 | "crtc %d failed to acquire vblank counter, %d\n",
|
| 2044 | pipe, ret);
|
| 2045 | return ret;
|
| 2046 | }
|
| 2047 | }
|
| 2048 | drm_modeset_lock(&crtc->mutex, NULL);
|
| 2049 | if (crtc->state)
|
| 2050 | get_seq->active = crtc->state->enable;
|
| 2051 | else
|
| 2052 | get_seq->active = crtc->enabled;
|
| 2053 | drm_modeset_unlock(&crtc->mutex);
|
| 2054 | get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now);
|
| 2055 | get_seq->sequence_ns = ktime_to_ns(now);
|
| 2056 | if (!vblank_enabled)
|
| 2057 | drm_crtc_vblank_put(crtc);
|
| 2058 | return 0;
|
| 2059 | }
|
| 2060 |
|
| 2061 | |
| 2062 | * Queue a event for VBLANK sequence
|
| 2063 | *
|
| 2064 | * \param dev DRM device
|
| 2065 | * \param data user argument, pointing to a drm_crtc_queue_sequence structure.
|
| 2066 | * \param file_priv drm file private for the user's open file descriptor
|
| 2067 |
|
| 2068 |
|
| 2069 | int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
|
| 2070 | struct drm_file *file_priv)
|
| 2071 | {
|
| 2072 | struct drm_crtc *crtc;
|
| 2073 | struct drm_vblank_crtc *vblank;
|
| 2074 | int pipe;
|
| 2075 | struct drm_crtc_queue_sequence *queue_seq = data;
|
| 2076 | ktime_t now;
|
| 2077 | struct drm_pending_vblank_event *e;
|
| 2078 | u32 flags;
|
| 2079 | u64 seq;
|
| 2080 | u64 req_seq;
|
| 2081 | int ret;
|
| 2082 |
|
| 2083 | if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
| 2084 | return -EOPNOTSUPP;
|
| 2085 |
|
| 2086 | if (!drm_dev_has_vblank(dev))
|
| 2087 | return -EOPNOTSUPP;
|
| 2088 |
|
| 2089 | crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id);
|
| 2090 | if (!crtc)
|
| 2091 | return -ENOENT;
|
| 2092 |
|
| 2093 | flags = queue_seq->flags;
|
| 2094 |
|
| 2095 | if (flags & ~(DRM_CRTC_SEQUENCE_RELATIVE|
|
| 2096 | DRM_CRTC_SEQUENCE_NEXT_ON_MISS))
|
| 2097 | return -EINVAL;
|
| 2098 |
|
| 2099 | pipe = drm_crtc_index(crtc);
|
| 2100 |
|
| 2101 | vblank = drm_crtc_vblank_crtc(crtc);
|
| 2102 |
|
| 2103 | e = kzalloc_obj(*e);
|
| 2104 | if (e == NULL)
|
| 2105 | return -ENOMEM;
|
| 2106 |
|
| 2107 | ret = drm_crtc_vblank_get(crtc);
|
| 2108 | if (ret) {
|
| 2109 | drm_dbg_core(dev,
|
| 2110 | "crtc %d failed to acquire vblank counter, %d\n",
|
| 2111 | pipe, ret);
|
| 2112 | goto err_free;
|
| 2113 | }
|
| 2114 |
|
| 2115 | seq = drm_vblank_count_and_time(dev, pipe, &now);
|
| 2116 | req_seq = queue_seq->sequence;
|
| 2117 |
|
| 2118 | if (flags & DRM_CRTC_SEQUENCE_RELATIVE)
|
| 2119 | req_seq += seq;
|
| 2120 |
|
| 2121 | if ((flags & DRM_CRTC_SEQUENCE_NEXT_ON_MISS) && drm_vblank_passed(seq, req_seq))
|
| 2122 | req_seq = seq + 1;
|
| 2123 |
|
| 2124 | e->pipe = pipe;
|
| 2125 | e->event.base.type = DRM_EVENT_CRTC_SEQUENCE;
|
| 2126 | e->event.base.length = sizeof(e->event.seq);
|
| 2127 | e->event.seq.user_data = queue_seq->user_data;
|
| 2128 |
|
| 2129 | spin_lock_irq(&dev->event_lock);
|
| 2130 |
|
| 2131 | |
| 2132 | * drm_crtc_vblank_off() might have been called after we called
|
| 2133 | * drm_crtc_vblank_get(). drm_crtc_vblank_off() holds event_lock around the
|
| 2134 | * vblank disable, so no need for further locking. The reference from
|
| 2135 | * drm_crtc_vblank_get() protects against vblank disable from another source.
|
| 2136 |
|
| 2137 | if (!READ_ONCE(vblank->enabled)) {
|
| 2138 | ret = -EINVAL;
|
| 2139 | goto err_unlock;
|
| 2140 | }
|
| 2141 |
|
| 2142 | ret = drm_event_reserve_init_locked(dev, file_priv, &e->base,
|
| 2143 | &e->event.base);
|
| 2144 |
|
| 2145 | if (ret)
|
| 2146 | goto err_unlock;
|
| 2147 |
|
| 2148 | e->sequence = req_seq;
|
| 2149 |
|
| 2150 | if (drm_vblank_passed(seq, req_seq)) {
|
| 2151 | drm_crtc_vblank_put(crtc);
|
| 2152 | send_vblank_event(dev, e, seq, now);
|
| 2153 | queue_seq->sequence = seq;
|
| 2154 | } else {
|
| 2155 |
|
| 2156 | list_add_tail(&e->base.link, &dev->vblank_event_list);
|
| 2157 | queue_seq->sequence = req_seq;
|
| 2158 | }
|
| 2159 |
|
| 2160 | spin_unlock_irq(&dev->event_lock);
|
| 2161 | return 0;
|
| 2162 |
|
| 2163 | err_unlock:
|
| 2164 | spin_unlock_irq(&dev->event_lock);
|
| 2165 | drm_crtc_vblank_put(crtc);
|
| 2166 | err_free:
|
| 2167 | kfree(e);
|
| 2168 | return ret;
|
| 2169 | }
|
| 2170 |
|
| 2171 | |
| 2172 | * VBLANK timer
|
| 2173 |
|
| 2174 |
|
| 2175 | static enum hrtimer_restart drm_vblank_timer_function(struct hrtimer *timer)
|
| 2176 | {
|
| 2177 | struct drm_vblank_crtc_timer *vtimer =
|
| 2178 | container_of(timer, struct drm_vblank_crtc_timer, timer);
|
| 2179 | struct drm_crtc *crtc = vtimer->crtc;
|
| 2180 | const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
| 2181 | struct drm_device *dev = crtc->dev;
|
| 2182 | unsigned long flags;
|
| 2183 | ktime_t interval;
|
| 2184 | u64 ret_overrun;
|
| 2185 | bool succ;
|
| 2186 |
|
| 2187 | spin_lock_irqsave(&vtimer->interval_lock, flags);
|
| 2188 | interval = vtimer->interval;
|
| 2189 | spin_unlock_irqrestore(&vtimer->interval_lock, flags);
|
| 2190 |
|
| 2191 | if (!interval)
|
| 2192 | return HRTIMER_NORESTART;
|
| 2193 |
|
| 2194 | ret_overrun = hrtimer_forward_now(&vtimer->timer, interval);
|
| 2195 | if (ret_overrun != 1)
|
| 2196 | drm_dbg_vbl(dev, "vblank timer overrun\n");
|
| 2197 |
|
| 2198 | if (crtc_funcs->handle_vblank_timeout)
|
| 2199 | succ = crtc_funcs->handle_vblank_timeout(crtc);
|
| 2200 | else
|
| 2201 | succ = drm_crtc_handle_vblank(crtc);
|
| 2202 | if (!succ)
|
| 2203 | return HRTIMER_NORESTART;
|
| 2204 |
|
| 2205 | return HRTIMER_RESTART;
|
| 2206 | }
|
| 2207 |
|
| 2208 | |
| 2209 | * drm_crtc_vblank_start_timer - Starts the vblank timer on the given CRTC
|
| 2210 | * @crtc: the CRTC
|
| 2211 | *
|
| 2212 | * Drivers should call this function from their CRTC's enable_vblank
|
| 2213 | * function to start a vblank timer. The timer will fire after the duration
|
| 2214 | * of a full frame. drm_crtc_vblank_cancel_timer() disables a running timer.
|
| 2215 | *
|
| 2216 | * Returns:
|
| 2217 | * 0 on success, or a negative errno code otherwise.
|
| 2218 |
|
| 2219 | int drm_crtc_vblank_start_timer(struct drm_crtc *crtc)
|
| 2220 | {
|
| 2221 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 2222 | struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
|
| 2223 | unsigned long flags;
|
| 2224 |
|
| 2225 | if (!vtimer->crtc) {
|
| 2226 | |
| 2227 | * Set up the data structures on the first invocation.
|
| 2228 |
|
| 2229 | vtimer->crtc = crtc;
|
| 2230 | spin_lock_init(&vtimer->interval_lock);
|
| 2231 | hrtimer_setup(&vtimer->timer, drm_vblank_timer_function,
|
| 2232 | CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
| 2233 | } else {
|
| 2234 | |
| 2235 | * Timer should not be active. If it is, wait for the
|
| 2236 | * previous cancel operations to finish.
|
| 2237 |
|
| 2238 | while (hrtimer_active(&vtimer->timer))
|
| 2239 | hrtimer_try_to_cancel(&vtimer->timer);
|
| 2240 | }
|
| 2241 |
|
| 2242 | drm_calc_timestamping_constants(crtc, &crtc->mode);
|
| 2243 |
|
| 2244 | spin_lock_irqsave(&vtimer->interval_lock, flags);
|
| 2245 | vtimer->interval = ns_to_ktime(vblank->framedur_ns);
|
| 2246 | spin_unlock_irqrestore(&vtimer->interval_lock, flags);
|
| 2247 |
|
| 2248 | hrtimer_start(&vtimer->timer, vtimer->interval, HRTIMER_MODE_REL);
|
| 2249 |
|
| 2250 | return 0;
|
| 2251 | }
|
| 2252 | EXPORT_SYMBOL(drm_crtc_vblank_start_timer);
|
| 2253 |
|
| 2254 | |
| 2255 | * drm_crtc_vblank_cancel_timer - Cancels the given CRTC's vblank timer
|
| 2256 | * @crtc: the CRTC
|
| 2257 | *
|
| 2258 | * Drivers should call this function from their CRTC's disable_vblank
|
| 2259 | * function to stop a vblank timer.
|
| 2260 |
|
| 2261 | void drm_crtc_vblank_cancel_timer(struct drm_crtc *crtc)
|
| 2262 | {
|
| 2263 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 2264 | struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
|
| 2265 | unsigned long flags;
|
| 2266 |
|
| 2267 | |
| 2268 | * Calling hrtimer_cancel() can result in a deadlock with DRM's
|
| 2269 | * vblank_time_lime_lock and hrtimers' softirq_expiry_lock. So
|
| 2270 | * clear interval and indicate cancellation. The timer function
|
| 2271 | * will cancel itself on the next invocation.
|
| 2272 |
|
| 2273 |
|
| 2274 | spin_lock_irqsave(&vtimer->interval_lock, flags);
|
| 2275 | vtimer->interval = 0;
|
| 2276 | spin_unlock_irqrestore(&vtimer->interval_lock, flags);
|
| 2277 |
|
| 2278 | hrtimer_try_to_cancel(&vtimer->timer);
|
| 2279 | }
|
| 2280 | EXPORT_SYMBOL(drm_crtc_vblank_cancel_timer);
|
| 2281 |
|
| 2282 | |
| 2283 | * drm_crtc_vblank_get_vblank_timeout - Returns the vblank timeout
|
| 2284 | * @crtc: The CRTC
|
| 2285 | * @vblank_time: Returns the next vblank timestamp
|
| 2286 | *
|
| 2287 | * The helper drm_crtc_vblank_get_vblank_timeout() returns the next vblank
|
| 2288 | * timestamp of the CRTC's vblank timer according to the timer's expiry
|
| 2289 | * time.
|
| 2290 |
|
| 2291 | void drm_crtc_vblank_get_vblank_timeout(struct drm_crtc *crtc, ktime_t *vblank_time)
|
| 2292 | {
|
| 2293 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
| 2294 | struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
|
| 2295 | u64 cur_count;
|
| 2296 | ktime_t cur_time;
|
| 2297 |
|
| 2298 | if (!READ_ONCE(vblank->enabled)) {
|
| 2299 | *vblank_time = ktime_get();
|
| 2300 | return;
|
| 2301 | }
|
| 2302 |
|
| 2303 | |
| 2304 | * A concurrent vblank timeout could update the expires field before
|
| 2305 | * we compare it with the vblank time. Hence we'd compare the old
|
| 2306 | * expiry time to the new vblank time; deducing the timer had already
|
| 2307 | * expired. Reread until we get consistent values from both fields.
|
| 2308 |
|
| 2309 | do {
|
| 2310 | cur_count = drm_crtc_vblank_count_and_time(crtc, &cur_time);
|
| 2311 | *vblank_time = READ_ONCE(vtimer->timer.node.expires);
|
| 2312 | } while (cur_count != drm_crtc_vblank_count_and_time(crtc, &cur_time));
|
| 2313 |
|
| 2314 | if (drm_WARN_ON(crtc->dev, !ktime_compare(*vblank_time, cur_time)))
|
| 2315 | return;
|
| 2316 |
|
| 2317 | |
| 2318 | * To prevent races we roll the hrtimer forward before we do any
|
| 2319 | * interrupt processing - this is how real hw works (the interrupt
|
| 2320 | * is only generated after all the vblank registers are updated)
|
| 2321 | * and what the vblank core expects. Therefore we need to always
|
| 2322 | * correct the timestamp by one frame.
|
| 2323 |
|
| 2324 | *vblank_time = ktime_sub(*vblank_time, vtimer->interval);
|
| 2325 | }
|
| 2326 | EXPORT_SYMBOL(drm_crtc_vblank_get_vblank_timeout);
|