Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck...
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_ringbuffer.c
index 3a02425..cb3508f 100644 (file)
@@ -220,9 +220,13 @@ static int init_render_ring(struct drm_device *dev,
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        int ret = init_ring_common(dev, ring);
+       int mode;
+
        if (IS_I9XX(dev) && !IS_GEN3(dev)) {
-               I915_WRITE(MI_MODE,
-                               (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+               mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
+               if (IS_GEN6(dev))
+                       mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
+               I915_WRITE(MI_MODE, mode);
        }
        return ret;
 }
@@ -535,7 +539,16 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
                intel_ring_advance(dev, ring);
        }
 
+       if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
+               intel_ring_begin(dev, ring, 2);
+               intel_ring_emit(dev, ring, MI_FLUSH |
+                               MI_NO_WRITE_FLUSH |
+                               MI_INVALIDATE_ISP );
+               intel_ring_emit(dev, ring, MI_NOOP);
+               intel_ring_advance(dev, ring);
+       }
        /* XXX breadcrumb */
+
        return 0;
 }
 
@@ -608,9 +621,10 @@ err:
 int intel_init_ring_buffer(struct drm_device *dev,
                struct intel_ring_buffer *ring)
 {
-       int ret;
        struct drm_i915_gem_object *obj_priv;
        struct drm_gem_object *obj;
+       int ret;
+
        ring->dev = dev;
 
        if (I915_NEED_GFX_HWS(dev)) {
@@ -623,16 +637,14 @@ int intel_init_ring_buffer(struct drm_device *dev,
        if (obj == NULL) {
                DRM_ERROR("Failed to allocate ringbuffer\n");
                ret = -ENOMEM;
-               goto cleanup;
+               goto err_hws;
        }
 
        ring->gem_object = obj;
 
        ret = i915_gem_object_pin(obj, ring->alignment);
-       if (ret != 0) {
-               drm_gem_object_unreference(obj);
-               goto cleanup;
-       }
+       if (ret)
+               goto err_unref;
 
        obj_priv = to_intel_bo(obj);
        ring->map.size = ring->size;
@@ -644,18 +656,14 @@ int intel_init_ring_buffer(struct drm_device *dev,
        drm_core_ioremap_wc(&ring->map, dev);
        if (ring->map.handle == NULL) {
                DRM_ERROR("Failed to map ringbuffer.\n");
-               i915_gem_object_unpin(obj);
-               drm_gem_object_unreference(obj);
                ret = -EINVAL;
-               goto cleanup;
+               goto err_unpin;
        }
 
        ring->virtual_start = ring->map.handle;
        ret = ring->init(dev, ring);
-       if (ret != 0) {
-               intel_cleanup_ring_buffer(dev, ring);
-               return ret;
-       }
+       if (ret)
+               goto err_unmap;
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                i915_kernel_lost_context(dev);
@@ -669,7 +677,15 @@ int intel_init_ring_buffer(struct drm_device *dev,
        INIT_LIST_HEAD(&ring->active_list);
        INIT_LIST_HEAD(&ring->request_list);
        return ret;
-cleanup:
+
+err_unmap:
+       drm_core_ioremapfree(&ring->map, dev);
+err_unpin:
+       i915_gem_object_unpin(obj);
+err_unref:
+       drm_gem_object_unreference(obj);
+       ring->gem_object = NULL;
+err_hws:
        cleanup_status_page(dev, ring);
        return ret;
 }