Commit fede5c91c4a8a7701d205b2b84b9835ddc7d6f02
Committed by
Dave Airlie
1 parent
f51c5b6e62
Exists in
master
and in
7 other branches
drm: Add a debug node for vblank state.
Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@linux.ie>
Showing 3 changed files with 73 additions and 0 deletions Side-by-side Diff
drivers/gpu/drm/drm_irq.c
... | ... | @@ -116,6 +116,9 @@ |
116 | 116 | dev->num_crtcs, DRM_MEM_DRIVER); |
117 | 117 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, |
118 | 118 | DRM_MEM_DRIVER); |
119 | + drm_free(dev->last_vblank_wait, | |
120 | + sizeof(*dev->last_vblank_wait) * dev->num_crtcs, | |
121 | + DRM_MEM_DRIVER); | |
119 | 122 | drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * |
120 | 123 | dev->num_crtcs, DRM_MEM_DRIVER); |
121 | 124 | |
... | ... | @@ -161,6 +164,11 @@ |
161 | 164 | if (!dev->last_vblank) |
162 | 165 | goto err; |
163 | 166 | |
167 | + dev->last_vblank_wait = drm_calloc(num_crtcs, sizeof(u32), | |
168 | + DRM_MEM_DRIVER); | |
169 | + if (!dev->last_vblank_wait) | |
170 | + goto err; | |
171 | + | |
164 | 172 | dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), |
165 | 173 | DRM_MEM_DRIVER); |
166 | 174 | if (!dev->vblank_inmodeset) |
... | ... | @@ -642,6 +650,7 @@ |
642 | 650 | } else { |
643 | 651 | DRM_DEBUG("waiting on vblank count %d, crtc %d\n", |
644 | 652 | vblwait->request.sequence, crtc); |
653 | + dev->last_vblank_wait[crtc] = vblwait->request.sequence; | |
645 | 654 | DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, |
646 | 655 | ((drm_vblank_count(dev, crtc) |
647 | 656 | - vblwait->request.sequence) <= (1 << 23))); |
drivers/gpu/drm/drm_proc.c
... | ... | @@ -49,6 +49,8 @@ |
49 | 49 | int request, int *eof, void *data); |
50 | 50 | static int drm_bufs_info(char *buf, char **start, off_t offset, |
51 | 51 | int request, int *eof, void *data); |
52 | +static int drm_vblank_info(char *buf, char **start, off_t offset, | |
53 | + int request, int *eof, void *data); | |
52 | 54 | static int drm_gem_name_info(char *buf, char **start, off_t offset, |
53 | 55 | int request, int *eof, void *data); |
54 | 56 | static int drm_gem_object_info(char *buf, char **start, off_t offset, |
... | ... | @@ -72,6 +74,7 @@ |
72 | 74 | {"clients", drm_clients_info, 0}, |
73 | 75 | {"queues", drm_queues_info, 0}, |
74 | 76 | {"bufs", drm_bufs_info, 0}, |
77 | + {"vblank", drm_vblank_info, 0}, | |
75 | 78 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, |
76 | 79 | {"gem_objects", drm_gem_object_info, DRIVER_GEM}, |
77 | 80 | #if DRM_DEBUG_CODE |
... | ... | @@ -453,6 +456,66 @@ |
453 | 456 | |
454 | 457 | mutex_lock(&dev->struct_mutex); |
455 | 458 | ret = drm__bufs_info(buf, start, offset, request, eof, data); |
459 | + mutex_unlock(&dev->struct_mutex); | |
460 | + return ret; | |
461 | +} | |
462 | + | |
463 | +/** | |
464 | + * Called when "/proc/dri/.../vblank" is read. | |
465 | + * | |
466 | + * \param buf output buffer. | |
467 | + * \param start start of output data. | |
468 | + * \param offset requested start offset. | |
469 | + * \param request requested number of bytes. | |
470 | + * \param eof whether there is no more data to return. | |
471 | + * \param data private data. | |
472 | + * \return number of written bytes. | |
473 | + */ | |
474 | +static int drm__vblank_info(char *buf, char **start, off_t offset, int request, | |
475 | + int *eof, void *data) | |
476 | +{ | |
477 | + struct drm_minor *minor = (struct drm_minor *) data; | |
478 | + struct drm_device *dev = minor->dev; | |
479 | + int len = 0; | |
480 | + int crtc; | |
481 | + | |
482 | + if (offset > DRM_PROC_LIMIT) { | |
483 | + *eof = 1; | |
484 | + return 0; | |
485 | + } | |
486 | + | |
487 | + *start = &buf[offset]; | |
488 | + *eof = 0; | |
489 | + | |
490 | + for (crtc = 0; crtc < dev->num_crtcs; crtc++) { | |
491 | + DRM_PROC_PRINT("CRTC %d enable: %d\n", | |
492 | + crtc, atomic_read(&dev->vblank_refcount[crtc])); | |
493 | + DRM_PROC_PRINT("CRTC %d counter: %d\n", | |
494 | + crtc, drm_vblank_count(dev, crtc)); | |
495 | + DRM_PROC_PRINT("CRTC %d last wait: %d\n", | |
496 | + crtc, dev->last_vblank_wait[crtc]); | |
497 | + DRM_PROC_PRINT("CRTC %d in modeset: %d\n", | |
498 | + crtc, dev->vblank_inmodeset[crtc]); | |
499 | + } | |
500 | + | |
501 | + if (len > request + offset) | |
502 | + return request; | |
503 | + *eof = 1; | |
504 | + return len - offset; | |
505 | +} | |
506 | + | |
507 | +/** | |
508 | + * Simply calls _vblank_info() while holding the drm_device::struct_mutex lock. | |
509 | + */ | |
510 | +static int drm_vblank_info(char *buf, char **start, off_t offset, int request, | |
511 | + int *eof, void *data) | |
512 | +{ | |
513 | + struct drm_minor *minor = (struct drm_minor *) data; | |
514 | + struct drm_device *dev = minor->dev; | |
515 | + int ret; | |
516 | + | |
517 | + mutex_lock(&dev->struct_mutex); | |
518 | + ret = drm__vblank_info(buf, start, offset, request, eof, data); | |
456 | 519 | mutex_unlock(&dev->struct_mutex); |
457 | 520 | return ret; |
458 | 521 | } |
include/drm/drmP.h
... | ... | @@ -911,6 +911,7 @@ |
911 | 911 | int *vblank_enabled; /* so we don't call enable more than |
912 | 912 | once per disable */ |
913 | 913 | int *vblank_inmodeset; /* Display driver is setting mode */ |
914 | + u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */ | |
914 | 915 | struct timer_list vblank_disable_timer; |
915 | 916 | |
916 | 917 | u32 max_vblank_count; /**< size of vblank counter register */ |