diff options
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_proc.c | 63 | ||||
-rw-r--r-- | include/drm/drmP.h | 1 |
3 files changed, 73 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 1608f8dbfda0..724e505873cf 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -116,6 +116,9 @@ void drm_vblank_cleanup(struct drm_device *dev) | |||
116 | dev->num_crtcs, DRM_MEM_DRIVER); | 116 | dev->num_crtcs, DRM_MEM_DRIVER); |
117 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, | 117 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, |
118 | DRM_MEM_DRIVER); | 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 | drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * | 122 | drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * |
120 | dev->num_crtcs, DRM_MEM_DRIVER); | 123 | dev->num_crtcs, DRM_MEM_DRIVER); |
121 | 124 | ||
@@ -161,6 +164,11 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) | |||
161 | if (!dev->last_vblank) | 164 | if (!dev->last_vblank) |
162 | goto err; | 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 | dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), | 172 | dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), |
165 | DRM_MEM_DRIVER); | 173 | DRM_MEM_DRIVER); |
166 | if (!dev->vblank_inmodeset) | 174 | if (!dev->vblank_inmodeset) |
@@ -642,6 +650,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
642 | } else { | 650 | } else { |
643 | DRM_DEBUG("waiting on vblank count %d, crtc %d\n", | 651 | DRM_DEBUG("waiting on vblank count %d, crtc %d\n", |
644 | vblwait->request.sequence, crtc); | 652 | vblwait->request.sequence, crtc); |
653 | dev->last_vblank_wait[crtc] = vblwait->request.sequence; | ||
645 | DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, | 654 | DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, |
646 | ((drm_vblank_count(dev, crtc) | 655 | ((drm_vblank_count(dev, crtc) |
647 | - vblwait->request.sequence) <= (1 << 23))); | 656 | - vblwait->request.sequence) <= (1 << 23))); |
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index 7dbaa1a19ea4..8df849f66830 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -49,6 +49,8 @@ static int drm_queues_info(char *buf, char **start, off_t offset, | |||
49 | int request, int *eof, void *data); | 49 | int request, int *eof, void *data); |
50 | static int drm_bufs_info(char *buf, char **start, off_t offset, | 50 | static int drm_bufs_info(char *buf, char **start, off_t offset, |
51 | int request, int *eof, void *data); | 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 | static int drm_gem_name_info(char *buf, char **start, off_t offset, | 54 | static int drm_gem_name_info(char *buf, char **start, off_t offset, |
53 | int request, int *eof, void *data); | 55 | int request, int *eof, void *data); |
54 | static int drm_gem_object_info(char *buf, char **start, off_t offset, | 56 | static int drm_gem_object_info(char *buf, char **start, off_t offset, |
@@ -72,6 +74,7 @@ static struct drm_proc_list { | |||
72 | {"clients", drm_clients_info, 0}, | 74 | {"clients", drm_clients_info, 0}, |
73 | {"queues", drm_queues_info, 0}, | 75 | {"queues", drm_queues_info, 0}, |
74 | {"bufs", drm_bufs_info, 0}, | 76 | {"bufs", drm_bufs_info, 0}, |
77 | {"vblank", drm_vblank_info, 0}, | ||
75 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, | 78 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, |
76 | {"gem_objects", drm_gem_object_info, DRIVER_GEM}, | 79 | {"gem_objects", drm_gem_object_info, DRIVER_GEM}, |
77 | #if DRM_DEBUG_CODE | 80 | #if DRM_DEBUG_CODE |
@@ -458,6 +461,66 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | |||
458 | } | 461 | } |
459 | 462 | ||
460 | /** | 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); | ||
519 | mutex_unlock(&dev->struct_mutex); | ||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | /** | ||
461 | * Called when "/proc/dri/.../clients" is read. | 524 | * Called when "/proc/dri/.../clients" is read. |
462 | * | 525 | * |
463 | * \param buf output buffer. | 526 | * \param buf output buffer. |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7802c80f2b23..afb7858c068d 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -911,6 +911,7 @@ struct drm_device { | |||
911 | int *vblank_enabled; /* so we don't call enable more than | 911 | int *vblank_enabled; /* so we don't call enable more than |
912 | once per disable */ | 912 | once per disable */ |
913 | int *vblank_inmodeset; /* Display driver is setting mode */ | 913 | int *vblank_inmodeset; /* Display driver is setting mode */ |
914 | u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */ | ||
914 | struct timer_list vblank_disable_timer; | 915 | struct timer_list vblank_disable_timer; |
915 | 916 | ||
916 | u32 max_vblank_count; /**< size of vblank counter register */ | 917 | u32 max_vblank_count; /**< size of vblank counter register */ |