Commit fede5c91c4a8a7701d205b2b84b9835ddc7d6f02

Authored by Eric Anholt
Committed by Dave Airlie
1 parent f51c5b6e62

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 }
... ... @@ -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 */