diff options
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/drm.h | 21 | ||||
-rw-r--r-- | shared-core/i915_dma.c | 13 | ||||
-rw-r--r-- | shared-core/i915_irq.c | 7 |
3 files changed, 29 insertions, 12 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h index cbe83fd1..303a84b6 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -645,8 +645,14 @@ struct drm_set_version { #define DRM_FENCE_FLAG_EMIT 0x00000001 #define DRM_FENCE_FLAG_SHAREABLE 0x00000002 +/** + * On hardware with no interrupt events for operation completion, + * indicates that the kernel should sleep while waiting for any blocking + * operation to complete rather than spinning. + * + * Has no effect otherwise. + */ #define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004 -#define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008 #define DRM_FENCE_FLAG_NO_USER 0x00000010 /* Reserved for driver use */ @@ -795,13 +801,12 @@ struct drm_fence_arg { * with it as a result of this operation */ #define DRM_BO_HINT_DONT_FENCE 0x00000004 -/* - * Sleep while waiting for the operation to complete. - * Without this flag, the kernel will, instead, spin - * until this operation has completed. I'm not sure - * why you would ever want this, so please always - * provide DRM_BO_HINT_WAIT_LAZY to any operation - * which may block +/** + * On hardware with no interrupt events for operation completion, + * indicates that the kernel should sleep while waiting for any blocking + * operation to complete rather than spinning. + * + * Has no effect otherwise. */ #define DRM_BO_HINT_WAIT_LAZY 0x00000008 /* diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 28835a04..13332d24 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -804,6 +804,7 @@ struct i915_relocatee_info { unsigned page_offset; struct drm_bo_kmap_obj kmap; int is_iomem; + int idle; }; struct drm_i915_validate_buffer { @@ -859,6 +860,14 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, drm_bo_kunmap(&relocatee->kmap); relocatee->data_page = NULL; relocatee->offset = new_cmd_offset; + + if (unlikely(!relocatee->idle)) { + ret = drm_bo_wait(relocatee->buf, 0, 0, 0); + if (ret) + return ret; + relocatee->idle = 1; + } + ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT, 1, &relocatee->kmap); if (ret) { @@ -1002,10 +1011,6 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, } mutex_lock (&relocatee.buf->mutex); - ret = drm_bo_wait (relocatee.buf, 0, 0, FALSE); - if (ret) - goto out_err1; - while (reloc_user_ptr) { ret = i915_process_relocs(file_priv, buf_handle, &reloc_user_ptr, &relocatee, buffers, buf_count); if (ret) { diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index dad6ef86..b9d137f4 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -415,6 +415,13 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) if (i915_in_vblank(dev, pipe)) count++; #endif + /* count may be reset by other driver(e.g. 2D driver), + we have no way to know if it is wrapped or resetted + when count is zero. do a rough guess. + */ + if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2) + dev->last_vblank[pipe] = 0; + return count; } |