diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-11 08:46:53 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-11 08:46:53 -0400 |
commit | 336879b1da97fffc097f77c6d6f818660f2826f0 (patch) | |
tree | 4ddb4d1c5d2b67fb096c72e41d2a03b01a605041 /drivers/gpu/drm/drm_irq.c | |
parent | 3d3cbd84300e7be1e53083cac0f6f9c12978ecb4 (diff) | |
parent | fdcaa1dbb7c6ed419b10fb8cdb5001ab0a00538f (diff) |
Merge remote-tracking branch 'airlied/drm-next' into topic/vblank-rework
Dave asked me to do the backmerge before sending him the revised pull
request, so here we go. Nothing fancy in the conflicts, just a few
things changed right next to each another.
Conflicts:
drivers/gpu/drm/drm_irq.c
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 84 |
1 files changed, 71 insertions, 13 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 79836594030c..034297640b48 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -639,8 +639,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
639 | const struct drm_crtc *refcrtc, | 639 | const struct drm_crtc *refcrtc, |
640 | const struct drm_display_mode *mode) | 640 | const struct drm_display_mode *mode) |
641 | { | 641 | { |
642 | ktime_t stime, etime, mono_time_offset; | ||
643 | struct timeval tv_etime; | 642 | struct timeval tv_etime; |
643 | ktime_t stime, etime; | ||
644 | int vbl_status; | 644 | int vbl_status; |
645 | int vpos, hpos, i; | 645 | int vpos, hpos, i; |
646 | int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; | 646 | int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; |
@@ -685,13 +685,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
685 | vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos, | 685 | vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos, |
686 | &hpos, &stime, &etime); | 686 | &hpos, &stime, &etime); |
687 | 687 | ||
688 | /* | ||
689 | * Get correction for CLOCK_MONOTONIC -> CLOCK_REALTIME if | ||
690 | * CLOCK_REALTIME is requested. | ||
691 | */ | ||
692 | if (!drm_timestamp_monotonic) | ||
693 | mono_time_offset = ktime_get_monotonic_offset(); | ||
694 | |||
695 | /* Return as no-op if scanout query unsupported or failed. */ | 688 | /* Return as no-op if scanout query unsupported or failed. */ |
696 | if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { | 689 | if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { |
697 | DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", | 690 | DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", |
@@ -730,7 +723,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
730 | delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; | 723 | delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; |
731 | 724 | ||
732 | if (!drm_timestamp_monotonic) | 725 | if (!drm_timestamp_monotonic) |
733 | etime = ktime_sub(etime, mono_time_offset); | 726 | etime = ktime_mono_to_real(etime); |
734 | 727 | ||
735 | /* save this only for debugging purposes */ | 728 | /* save this only for debugging purposes */ |
736 | tv_etime = ktime_to_timeval(etime); | 729 | tv_etime = ktime_to_timeval(etime); |
@@ -761,10 +754,7 @@ static struct timeval get_drm_timestamp(void) | |||
761 | { | 754 | { |
762 | ktime_t now; | 755 | ktime_t now; |
763 | 756 | ||
764 | now = ktime_get(); | 757 | now = drm_timestamp_monotonic ? ktime_get() : ktime_get_real(); |
765 | if (!drm_timestamp_monotonic) | ||
766 | now = ktime_sub(now, ktime_get_monotonic_offset()); | ||
767 | |||
768 | return ktime_to_timeval(now); | 758 | return ktime_to_timeval(now); |
769 | } | 759 | } |
770 | 760 | ||
@@ -829,6 +819,8 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc) | |||
829 | { | 819 | { |
830 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; | 820 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; |
831 | 821 | ||
822 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
823 | return 0; | ||
832 | return atomic_read(&vblank->count); | 824 | return atomic_read(&vblank->count); |
833 | } | 825 | } |
834 | EXPORT_SYMBOL(drm_vblank_count); | 826 | EXPORT_SYMBOL(drm_vblank_count); |
@@ -852,6 +844,9 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, | |||
852 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; | 844 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; |
853 | u32 cur_vblank; | 845 | u32 cur_vblank; |
854 | 846 | ||
847 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
848 | return 0; | ||
849 | |||
855 | /* Read timestamp from slot of _vblank_time ringbuffer | 850 | /* Read timestamp from slot of _vblank_time ringbuffer |
856 | * that corresponds to current vblank count. Retry if | 851 | * that corresponds to current vblank count. Retry if |
857 | * count has incremented during readout. This works like | 852 | * count has incremented during readout. This works like |
@@ -965,6 +960,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc) | |||
965 | unsigned long irqflags; | 960 | unsigned long irqflags; |
966 | int ret = 0; | 961 | int ret = 0; |
967 | 962 | ||
963 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
964 | return -EINVAL; | ||
965 | |||
968 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 966 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
969 | /* Going from 0->1 means we have to enable interrupts again */ | 967 | /* Going from 0->1 means we have to enable interrupts again */ |
970 | if (atomic_add_return(1, &vblank->refcount) == 1) { | 968 | if (atomic_add_return(1, &vblank->refcount) == 1) { |
@@ -1015,6 +1013,9 @@ void drm_vblank_put(struct drm_device *dev, int crtc) | |||
1015 | 1013 | ||
1016 | BUG_ON(atomic_read(&vblank->refcount) == 0); | 1014 | BUG_ON(atomic_read(&vblank->refcount) == 0); |
1017 | 1015 | ||
1016 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1017 | return; | ||
1018 | |||
1018 | /* Last user schedules interrupt disable */ | 1019 | /* Last user schedules interrupt disable */ |
1019 | if (atomic_dec_and_test(&vblank->refcount)) { | 1020 | if (atomic_dec_and_test(&vblank->refcount)) { |
1020 | if (drm_vblank_offdelay == 0) | 1021 | if (drm_vblank_offdelay == 0) |
@@ -1044,6 +1045,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc) | |||
1044 | EXPORT_SYMBOL(drm_crtc_vblank_put); | 1045 | EXPORT_SYMBOL(drm_crtc_vblank_put); |
1045 | 1046 | ||
1046 | /** | 1047 | /** |
1048 | * drm_wait_one_vblank - wait for one vblank | ||
1049 | * @dev: DRM device | ||
1050 | * @crtc: crtc index | ||
1051 | * | ||
1052 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces. | ||
1053 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. | ||
1054 | * due to lack of driver support or because the crtc is off. | ||
1055 | */ | ||
1056 | void drm_wait_one_vblank(struct drm_device *dev, int crtc) | ||
1057 | { | ||
1058 | int ret; | ||
1059 | u32 last; | ||
1060 | |||
1061 | ret = drm_vblank_get(dev, crtc); | ||
1062 | if (WARN_ON(ret)) | ||
1063 | return; | ||
1064 | |||
1065 | last = drm_vblank_count(dev, crtc); | ||
1066 | |||
1067 | ret = wait_event_timeout(dev->vblank[crtc].queue, | ||
1068 | last != drm_vblank_count(dev, crtc), | ||
1069 | msecs_to_jiffies(100)); | ||
1070 | |||
1071 | WARN_ON(ret == 0); | ||
1072 | |||
1073 | drm_vblank_put(dev, crtc); | ||
1074 | } | ||
1075 | EXPORT_SYMBOL(drm_wait_one_vblank); | ||
1076 | |||
1077 | /** | ||
1078 | * drm_crtc_wait_one_vblank - wait for one vblank | ||
1079 | * @crtc: DRM crtc | ||
1080 | * | ||
1081 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces. | ||
1082 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. | ||
1083 | * due to lack of driver support or because the crtc is off. | ||
1084 | */ | ||
1085 | void drm_crtc_wait_one_vblank(struct drm_crtc *crtc) | ||
1086 | { | ||
1087 | drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc)); | ||
1088 | } | ||
1089 | EXPORT_SYMBOL(drm_crtc_wait_one_vblank); | ||
1090 | |||
1091 | /** | ||
1047 | * drm_vblank_off - disable vblank events on a CRTC | 1092 | * drm_vblank_off - disable vblank events on a CRTC |
1048 | * @dev: DRM device | 1093 | * @dev: DRM device |
1049 | * @crtc: CRTC in question | 1094 | * @crtc: CRTC in question |
@@ -1065,6 +1110,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc) | |||
1065 | unsigned long irqflags; | 1110 | unsigned long irqflags; |
1066 | unsigned int seq; | 1111 | unsigned int seq; |
1067 | 1112 | ||
1113 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1114 | return; | ||
1115 | |||
1068 | spin_lock_irqsave(&dev->event_lock, irqflags); | 1116 | spin_lock_irqsave(&dev->event_lock, irqflags); |
1069 | 1117 | ||
1070 | spin_lock(&dev->vbl_lock); | 1118 | spin_lock(&dev->vbl_lock); |
@@ -1134,6 +1182,9 @@ void drm_vblank_on(struct drm_device *dev, int crtc) | |||
1134 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; | 1182 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; |
1135 | unsigned long irqflags; | 1183 | unsigned long irqflags; |
1136 | 1184 | ||
1185 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1186 | return; | ||
1187 | |||
1137 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 1188 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
1138 | /* Drop our private "prevent drm_vblank_get" refcount */ | 1189 | /* Drop our private "prevent drm_vblank_get" refcount */ |
1139 | if (vblank->inmodeset) { | 1190 | if (vblank->inmodeset) { |
@@ -1209,6 +1260,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) | |||
1209 | /* vblank is not initialized (IRQ not installed ?), or has been freed */ | 1260 | /* vblank is not initialized (IRQ not installed ?), or has been freed */ |
1210 | if (!dev->num_crtcs) | 1261 | if (!dev->num_crtcs) |
1211 | return; | 1262 | return; |
1263 | |||
1264 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1265 | return; | ||
1266 | |||
1212 | /* | 1267 | /* |
1213 | * To avoid all the problems that might happen if interrupts | 1268 | * To avoid all the problems that might happen if interrupts |
1214 | * were enabled/disabled around or between these calls, we just | 1269 | * were enabled/disabled around or between these calls, we just |
@@ -1532,6 +1587,9 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1532 | if (!dev->num_crtcs) | 1587 | if (!dev->num_crtcs) |
1533 | return false; | 1588 | return false; |
1534 | 1589 | ||
1590 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1591 | return false; | ||
1592 | |||
1535 | spin_lock_irqsave(&dev->event_lock, irqflags); | 1593 | spin_lock_irqsave(&dev->event_lock, irqflags); |
1536 | 1594 | ||
1537 | /* Need timestamp lock to prevent concurrent execution with | 1595 | /* Need timestamp lock to prevent concurrent execution with |