@@ -303,7 +303,7 @@ int etnaviv_wait_fence_interruptable(struct drm_device *dev, uint32_t pipe,
if (!gpu)
return -ENXIO;
- if (fence > gpu->submitted_fence) {
+ if (fence_after(fence, gpu->submitted_fence)) {
DRM_ERROR("waiting on invalid fence: %u (of %u)\n",
fence, gpu->submitted_fence);
return -EINVAL;
@@ -344,7 +344,8 @@ void etnaviv_update_fence(struct drm_device *dev, uint32_t fence)
struct etnaviv_drm_private *priv = dev->dev_private;
mutex_lock(&dev->struct_mutex);
- priv->completed_fence = max(fence, priv->completed_fence);
+ if (fence_after(fence, priv->completed_fence))
+ priv->completed_fence = fence;
mutex_unlock(&dev->struct_mutex);
wake_up_all(&priv->fence_event);
@@ -127,10 +127,22 @@ u32 etnaviv_readl(const void __iomem *addr);
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+/* returns true if fence a comes after fence b */
+static inline bool fence_after(uint32_t a, uint32_t b)
+{
+ return (int32_t)(a - b) > 0;
+}
+
+static inline bool fence_after_eq(uint32_t a, uint32_t b)
+{
+ return (int32_t)(a - b) >= 0;
+}
+
static inline bool fence_completed(struct drm_device *dev, uint32_t fence)
{
struct etnaviv_drm_private *priv = dev->dev_private;
- return priv->completed_fence >= fence;
+
+ return fence_after_eq(priv->completed_fence, fence);
}
static inline int align_pitch(int width, int bpp)
@@ -648,7 +648,7 @@ static void hangcheck_handler(unsigned long data)
if (fence != gpu->hangcheck_fence) {
/* some progress has been made.. ya! */
gpu->hangcheck_fence = fence;
- } else if (fence < gpu->submitted_fence) {
+ } else if (fence_after(gpu->submitted_fence, fence)) {
/* no progress and not done.. hung! */
gpu->hangcheck_fence = fence;
dev_err(dev->dev, "%s: hangcheck detected gpu lockup!\n",
@@ -661,7 +661,7 @@ static void hangcheck_handler(unsigned long data)
}
/* if still more pending work, reset the hangcheck timer: */
- if (gpu->submitted_fence > gpu->hangcheck_fence)
+ if (fence_after(gpu->submitted_fence, gpu->hangcheck_fence))
hangcheck_timer_reset(gpu);
}