diff options
author | Dave Airlie <airlied@redhat.com> | 2014-08-25 19:04:03 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-08-25 19:04:03 -0400 |
commit | c0ee755fc57319a623e0d9ef839cf8fb26ce8d60 (patch) | |
tree | 727fe78a158757f75b54d7e037b383ad6a39843c /drivers/gpu/drm/drm_irq.c | |
parent | 52addcf9d6669fa439387610bc65c92fa0980cef (diff) | |
parent | 14f476fa24e81d0beea1aa14d763102958518d60 (diff) |
Merge tag 'topic/core-stuff-2014-08-15' of git://anongit.freedesktop.org/drm-intel into drm-next
So small drm stuff all over for 3.18. Biggest one is the cmdline parsing
from Chris with a few fixes from me to make it work for stupid kernel
configs.
Plus the atomic prep series.
Tested for more than a week in -nightly and Ville/Imre indeed discovered
some fun which is now fixed (and i915 vblank patches postponed since the
fixups need this branch plus drm-intel-next merged together).
* tag 'topic/core-stuff-2014-08-15' of git://anongit.freedesktop.org/drm-intel:
drm: Use the type of the array element when reallocating
drm: Don't return 0 for a value used as a denominator
drm: Docbook fixes
drm/irq: Implement a generic vblank_wait function
drm: Add a plane->reset hook
drm: trylock modest locking for fbdev panics
drm: Move ->old_fb from crtc to plane
drm: Handle legacy per-crtc locking with full acquire ctx
drm: Move modeset_lock_all helpers to drm_modeset_lock.[hc]
drm: Add drm_plane/connector_index
drm: idiot-proof vblank
drm: Warn when leaking flip events on close
drm: Perform cmdline mode parsing during connector initialisation
video/fbdev: Always built-in video= cmdline parsing
drm: Don't grab an fb reference for the idr
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 08ba1209228e..5708c056fa1b 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -720,6 +720,8 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp); | |||
720 | */ | 720 | */ |
721 | u32 drm_vblank_count(struct drm_device *dev, int crtc) | 721 | u32 drm_vblank_count(struct drm_device *dev, int crtc) |
722 | { | 722 | { |
723 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
724 | return 0; | ||
723 | return atomic_read(&dev->vblank[crtc].count); | 725 | return atomic_read(&dev->vblank[crtc].count); |
724 | } | 726 | } |
725 | EXPORT_SYMBOL(drm_vblank_count); | 727 | EXPORT_SYMBOL(drm_vblank_count); |
@@ -742,6 +744,9 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, | |||
742 | { | 744 | { |
743 | u32 cur_vblank; | 745 | u32 cur_vblank; |
744 | 746 | ||
747 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
748 | return 0; | ||
749 | |||
745 | /* Read timestamp from slot of _vblank_time ringbuffer | 750 | /* Read timestamp from slot of _vblank_time ringbuffer |
746 | * that corresponds to current vblank count. Retry if | 751 | * that corresponds to current vblank count. Retry if |
747 | * count has incremented during readout. This works like | 752 | * count has incremented during readout. This works like |
@@ -917,6 +922,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc) | |||
917 | unsigned long irqflags; | 922 | unsigned long irqflags; |
918 | int ret = 0; | 923 | int ret = 0; |
919 | 924 | ||
925 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
926 | return -EINVAL; | ||
927 | |||
920 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 928 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
921 | /* Going from 0->1 means we have to enable interrupts again */ | 929 | /* Going from 0->1 means we have to enable interrupts again */ |
922 | if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) { | 930 | if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) { |
@@ -965,6 +973,9 @@ void drm_vblank_put(struct drm_device *dev, int crtc) | |||
965 | { | 973 | { |
966 | BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0); | 974 | BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0); |
967 | 975 | ||
976 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
977 | return; | ||
978 | |||
968 | /* Last user schedules interrupt disable */ | 979 | /* Last user schedules interrupt disable */ |
969 | if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && | 980 | if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && |
970 | (drm_vblank_offdelay > 0)) | 981 | (drm_vblank_offdelay > 0)) |
@@ -989,6 +1000,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc) | |||
989 | EXPORT_SYMBOL(drm_crtc_vblank_put); | 1000 | EXPORT_SYMBOL(drm_crtc_vblank_put); |
990 | 1001 | ||
991 | /** | 1002 | /** |
1003 | * drm_wait_one_vblank - wait for one vblank | ||
1004 | * @dev: DRM device | ||
1005 | * @crtc: crtc index | ||
1006 | * | ||
1007 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces. | ||
1008 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. | ||
1009 | * due to lack of driver support or because the crtc is off. | ||
1010 | */ | ||
1011 | void drm_wait_one_vblank(struct drm_device *dev, int crtc) | ||
1012 | { | ||
1013 | int ret; | ||
1014 | u32 last; | ||
1015 | |||
1016 | ret = drm_vblank_get(dev, crtc); | ||
1017 | if (WARN_ON(ret)) | ||
1018 | return; | ||
1019 | |||
1020 | last = drm_vblank_count(dev, crtc); | ||
1021 | |||
1022 | ret = wait_event_timeout(dev->vblank[crtc].queue, | ||
1023 | last != drm_vblank_count(dev, crtc), | ||
1024 | msecs_to_jiffies(100)); | ||
1025 | |||
1026 | WARN_ON(ret == 0); | ||
1027 | |||
1028 | drm_vblank_put(dev, crtc); | ||
1029 | } | ||
1030 | EXPORT_SYMBOL(drm_wait_one_vblank); | ||
1031 | |||
1032 | /** | ||
1033 | * drm_crtc_wait_one_vblank - wait for one vblank | ||
1034 | * @crtc: DRM crtc | ||
1035 | * | ||
1036 | * This waits for one vblank to pass on @crtc, using the irq driver interfaces. | ||
1037 | * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. | ||
1038 | * due to lack of driver support or because the crtc is off. | ||
1039 | */ | ||
1040 | void drm_crtc_wait_one_vblank(struct drm_crtc *crtc) | ||
1041 | { | ||
1042 | drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc)); | ||
1043 | } | ||
1044 | EXPORT_SYMBOL(drm_crtc_wait_one_vblank); | ||
1045 | |||
1046 | /** | ||
992 | * drm_vblank_off - disable vblank events on a CRTC | 1047 | * drm_vblank_off - disable vblank events on a CRTC |
993 | * @dev: DRM device | 1048 | * @dev: DRM device |
994 | * @crtc: CRTC in question | 1049 | * @crtc: CRTC in question |
@@ -1009,6 +1064,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc) | |||
1009 | unsigned long irqflags; | 1064 | unsigned long irqflags; |
1010 | unsigned int seq; | 1065 | unsigned int seq; |
1011 | 1066 | ||
1067 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1068 | return; | ||
1069 | |||
1012 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 1070 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
1013 | vblank_disable_and_save(dev, crtc); | 1071 | vblank_disable_and_save(dev, crtc); |
1014 | wake_up(&dev->vblank[crtc].queue); | 1072 | wake_up(&dev->vblank[crtc].queue); |
@@ -1068,6 +1126,9 @@ void drm_vblank_on(struct drm_device *dev, int crtc) | |||
1068 | { | 1126 | { |
1069 | unsigned long irqflags; | 1127 | unsigned long irqflags; |
1070 | 1128 | ||
1129 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1130 | return; | ||
1131 | |||
1071 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 1132 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
1072 | /* re-enable interrupts if there's are users left */ | 1133 | /* re-enable interrupts if there's are users left */ |
1073 | if (atomic_read(&dev->vblank[crtc].refcount) != 0) | 1134 | if (atomic_read(&dev->vblank[crtc].refcount) != 0) |
@@ -1121,6 +1182,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) | |||
1121 | /* vblank is not initialized (IRQ not installed ?), or has been freed */ | 1182 | /* vblank is not initialized (IRQ not installed ?), or has been freed */ |
1122 | if (!dev->num_crtcs) | 1183 | if (!dev->num_crtcs) |
1123 | return; | 1184 | return; |
1185 | |||
1186 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1187 | return; | ||
1188 | |||
1124 | /* | 1189 | /* |
1125 | * To avoid all the problems that might happen if interrupts | 1190 | * To avoid all the problems that might happen if interrupts |
1126 | * were enabled/disabled around or between these calls, we just | 1191 | * were enabled/disabled around or between these calls, we just |
@@ -1429,6 +1494,9 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1429 | if (!dev->num_crtcs) | 1494 | if (!dev->num_crtcs) |
1430 | return false; | 1495 | return false; |
1431 | 1496 | ||
1497 | if (WARN_ON(crtc >= dev->num_crtcs)) | ||
1498 | return false; | ||
1499 | |||
1432 | /* Need timestamp lock to prevent concurrent execution with | 1500 | /* Need timestamp lock to prevent concurrent execution with |
1433 | * vblank enable/disable, as this would cause inconsistent | 1501 | * vblank enable/disable, as this would cause inconsistent |
1434 | * or corrupted timestamps and vblank counts. | 1502 | * or corrupted timestamps and vblank counts. |