]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/i915_gem.c
Merge tag 'drm-intel-fixes-2015-03-19' into drm-intel-next
[karo-tx-linux.git] / drivers / gpu / drm / i915 / i915_gem.c
index 5b205863b6596d7fa72e6f465a017d9bcb204e78..0fe313d0f6092d3e1db873cc6a7999feb0557eca 100644 (file)
@@ -29,6 +29,7 @@
 #include <drm/drm_vma_manager.h>
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
+#include "i915_vgpu.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
 #include <linux/oom.h>
@@ -350,7 +351,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
        struct drm_device *dev = obj->base.dev;
        void *vaddr = obj->phys_handle->vaddr + args->offset;
        char __user *user_data = to_user_ptr(args->data_ptr);
-       int ret;
+       int ret = 0;
 
        /* We manually control the domain here and pretend that it
         * remains coherent i.e. in the GTT domain, like shmem_pwrite.
@@ -359,6 +360,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
        if (ret)
                return ret;
 
+       intel_fb_obj_invalidate(obj, NULL, ORIGIN_CPU);
        if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
                unsigned long unwritten;
 
@@ -369,13 +371,18 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
                mutex_unlock(&dev->struct_mutex);
                unwritten = copy_from_user(vaddr, user_data, args->size);
                mutex_lock(&dev->struct_mutex);
-               if (unwritten)
-                       return -EFAULT;
+               if (unwritten) {
+                       ret = -EFAULT;
+                       goto out;
+               }
        }
 
        drm_clflush_virt_range(vaddr, args->size);
        i915_gem_chipset_flush(dev);
-       return 0;
+
+out:
+       intel_fb_obj_flush(obj, false);
+       return ret;
 }
 
 void *i915_gem_object_alloc(struct drm_device *dev)
@@ -809,6 +816,8 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
 
        offset = i915_gem_obj_ggtt_offset(obj) + args->offset;
 
+       intel_fb_obj_invalidate(obj, NULL, ORIGIN_GTT);
+
        while (remain > 0) {
                /* Operation in this page
                 *
@@ -829,7 +838,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
                if (fast_user_write(dev_priv->gtt.mappable, page_base,
                                    page_offset, user_data, page_length)) {
                        ret = -EFAULT;
-                       goto out_unpin;
+                       goto out_flush;
                }
 
                remain -= page_length;
@@ -837,6 +846,8 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
                offset += page_length;
        }
 
+out_flush:
+       intel_fb_obj_flush(obj, false);
 out_unpin:
        i915_gem_object_ggtt_unpin(obj);
 out:
@@ -951,6 +962,8 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
        if (ret)
                return ret;
 
+       intel_fb_obj_invalidate(obj, NULL, ORIGIN_CPU);
+
        i915_gem_object_pin_pages(obj);
 
        offset = args->offset;
@@ -1029,6 +1042,7 @@ out:
        if (needs_clflush_after)
                i915_gem_chipset_flush(dev);
 
+       intel_fb_obj_flush(obj, false);
        return ret;
 }
 
@@ -2492,6 +2506,8 @@ int __i915_add_request(struct intel_engine_cs *ring,
                list_add_tail(&request->client_list,
                              &file_priv->mm.request_list);
                spin_unlock(&file_priv->mm.lock);
+
+               request->pid = get_pid(task_pid(current));
        }
 
        trace_i915_gem_request_add(request);
@@ -2572,6 +2588,8 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request)
        list_del(&request->list);
        i915_gem_request_remove_from_client(request);
 
+       put_pid(request->pid);
+
        i915_gem_request_unreference(request);
 }
 
@@ -2757,7 +2775,6 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 
        while (!list_empty(&ring->request_list)) {
                struct drm_i915_gem_request *request;
-               struct intel_ringbuffer *ringbuf;
 
                request = list_first_entry(&ring->request_list,
                                           struct drm_i915_gem_request,
@@ -2768,23 +2785,12 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 
                trace_i915_gem_request_retire(request);
 
-               /* This is one of the few common intersection points
-                * between legacy ringbuffer submission and execlists:
-                * we need to tell them apart in order to find the correct
-                * ringbuffer to which the request belongs to.
-                */
-               if (i915.enable_execlists) {
-                       struct intel_context *ctx = request->ctx;
-                       ringbuf = ctx->engine[ring->id].ringbuf;
-               } else
-                       ringbuf = ring->buffer;
-
                /* We know the GPU must have read the request to have
                 * sent us the seqno + interrupt, so use the position
                 * of tail of the request to update the last known position
                 * of the GPU head.
                 */
-               ringbuf->last_retired_head = request->postfix;
+               request->ringbuf->last_retired_head = request->postfix;
 
                i915_gem_free_request(request);
        }
@@ -3764,7 +3770,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
        }
 
        if (write)
-               intel_fb_obj_invalidate(obj, NULL);
+               intel_fb_obj_invalidate(obj, NULL, ORIGIN_GTT);
 
        trace_i915_gem_object_change_domain(obj,
                                            old_read_domains,
@@ -4079,7 +4085,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
        }
 
        if (write)
-               intel_fb_obj_invalidate(obj, NULL);
+               intel_fb_obj_invalidate(obj, NULL, ORIGIN_CPU);
 
        trace_i915_gem_object_change_domain(obj,
                                            old_read_domains,
@@ -4233,7 +4239,7 @@ i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
                fenceable = (vma->node.size == fence_size &&
                             (vma->node.start & (fence_alignment - 1)) == 0);
 
-               mappable = (vma->node.start + obj->base.size <=
+               mappable = (vma->node.start + fence_size <=
                            dev_priv->gtt.mappable_end);
 
                obj->map_and_fenceable = mappable && fenceable;
@@ -4608,10 +4614,6 @@ i915_gem_suspend(struct drm_device *dev)
 
        i915_gem_retire_requests(dev);
 
-       /* Under UMS, be paranoid and evict. */
-       if (!drm_core_check_feature(dev, DRIVER_MODESET))
-               i915_gem_evict_everything(dev);
-
        i915_gem_stop_ringbuffers(dev);
        mutex_unlock(&dev->struct_mutex);
 
@@ -4982,18 +4984,8 @@ i915_gem_load(struct drm_device *dev)
                          i915_gem_idle_work_handler);
        init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
 
-       /* On GEN3 we really need to make sure the ARB C3 LP bit is set */
-       if (!drm_core_check_feature(dev, DRIVER_MODESET) && IS_GEN3(dev)) {
-               I915_WRITE(MI_ARB_STATE,
-                          _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
-       }
-
        dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL;
 
-       /* Old X drivers will take 0-2 for front, back, depth buffers */
-       if (!drm_core_check_feature(dev, DRIVER_MODESET))
-               dev_priv->fence_reg_start = 3;
-
        if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev))
                dev_priv->num_fence_regs = 32;
        else if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
@@ -5001,6 +4993,10 @@ i915_gem_load(struct drm_device *dev)
        else
                dev_priv->num_fence_regs = 8;
 
+       if (intel_vgpu_active(dev))
+               dev_priv->num_fence_regs =
+                               I915_READ(vgtif_reg(avail_rs.fence_num));
+
        /* Initialize fence registers to zero */
        INIT_LIST_HEAD(&dev_priv->mm.fence_list);
        i915_gem_restore_fences(dev);