drm: remove address mask param for drm_pci_alloc()
[safe/jmp/linux-2.6] / drivers / gpu / drm / i915 / i915_gem.c
index 5e579a4..c7f0cbe 100644 (file)
@@ -1288,6 +1288,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
        list->hash.key = list->file_offset_node->start;
        if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) {
                DRM_ERROR("failed to add to map hash\n");
+               ret = -ENOMEM;
                goto out_free_mm;
        }
 
@@ -1617,7 +1618,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
        OUT_RING(MI_USER_INTERRUPT);
        ADVANCE_LP_RING();
 
-       DRM_DEBUG("%d\n", seqno);
+       DRM_DEBUG_DRIVER("%d\n", seqno);
 
        request->seqno = seqno;
        request->emitted_jiffies = jiffies;
@@ -1833,7 +1834,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
                return -EIO;
 
        if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
-               if (IS_IGDNG(dev))
+               if (IS_IRONLAKE(dev))
                        ier = I915_READ(DEIER) | I915_READ(GTIER);
                else
                        ier = I915_READ(IER);
@@ -1890,24 +1891,6 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
        return i915_do_wait_request(dev, seqno, 1);
 }
 
-/**
- * Waits for the ring to finish up to the latest request. Usefull for waiting
- * for flip events, e.g for the overlay support. */
-int i915_lp_ring_sync(struct drm_device *dev)
-{
-       uint32_t seqno;
-       int ret;
-
-       seqno = i915_add_request(dev, NULL, 0);
-
-       if (seqno == 0)
-               return -ENOMEM;
-
-       ret = i915_do_wait_request(dev, seqno, 0);
-       BUG_ON(ret == -ERESTARTSYS);
-       return ret;
-}
-
 static void
 i915_gem_flush(struct drm_device *dev,
               uint32_t invalidate_domains,
@@ -2789,6 +2772,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
                                            old_write_domain);
 }
 
+void
+i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
+{
+       switch (obj->write_domain) {
+       case I915_GEM_DOMAIN_GTT:
+               i915_gem_object_flush_gtt_write_domain(obj);
+               break;
+       case I915_GEM_DOMAIN_CPU:
+               i915_gem_object_flush_cpu_write_domain(obj);
+               break;
+       default:
+               i915_gem_object_flush_gpu_write_domain(obj);
+               break;
+       }
+}
+
 /**
  * Moves a single object to the GTT read, and possibly write domain.
  *
@@ -3554,6 +3553,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec,
        return 0;
 }
 
+static int
+i915_gem_wait_for_pending_flip(struct drm_device *dev,
+                              struct drm_gem_object **object_list,
+                              int count)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_gem_object *obj_priv;
+       DEFINE_WAIT(wait);
+       int i, ret = 0;
+
+       for (;;) {
+               prepare_to_wait(&dev_priv->pending_flip_queue,
+                               &wait, TASK_INTERRUPTIBLE);
+               for (i = 0; i < count; i++) {
+                       obj_priv = object_list[i]->driver_private;
+                       if (atomic_read(&obj_priv->pending_flip) > 0)
+                               break;
+               }
+               if (i == count)
+                       break;
+
+               if (!signal_pending(current)) {
+                       mutex_unlock(&dev->struct_mutex);
+                       schedule();
+                       mutex_lock(&dev->struct_mutex);
+                       continue;
+               }
+               ret = -ERESTARTSYS;
+               break;
+       }
+       finish_wait(&dev_priv->pending_flip_queue, &wait);
+
+       return ret;
+}
+
 int
 i915_gem_execbuffer(struct drm_device *dev, void *data,
                    struct drm_file *file_priv)
@@ -3569,7 +3603,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
        int ret, ret2, i, pinned = 0;
        uint64_t exec_offset;
        uint32_t seqno, flush_domains, reloc_index;
-       int pin_tries;
+       int pin_tries, flips;
 
 #if WATCH_EXEC
        DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@@ -3581,8 +3615,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
                return -EINVAL;
        }
        /* Copy in the exec list from userland */
-       exec_list = drm_calloc_large(sizeof(*exec_list), args->buffer_count);
-       object_list = drm_calloc_large(sizeof(*object_list), args->buffer_count);
+       exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
+       object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count);
        if (exec_list == NULL || object_list == NULL) {
                DRM_ERROR("Failed to allocate exec or object list "
                          "for %d buffers\n",
@@ -3627,20 +3661,19 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
        i915_verify_inactive(dev, __FILE__, __LINE__);
 
        if (atomic_read(&dev_priv->mm.wedged)) {
-               DRM_ERROR("Execbuf while wedged\n");
                mutex_unlock(&dev->struct_mutex);
                ret = -EIO;
                goto pre_mutex_err;
        }
 
        if (dev_priv->mm.suspended) {
-               DRM_ERROR("Execbuf while VT-switched.\n");
                mutex_unlock(&dev->struct_mutex);
                ret = -EBUSY;
                goto pre_mutex_err;
        }
 
        /* Look up object handles */
+       flips = 0;
        for (i = 0; i < args->buffer_count; i++) {
                object_list[i] = drm_gem_object_lookup(dev, file_priv,
                                                       exec_list[i].handle);
@@ -3659,6 +3692,14 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
                        goto err;
                }
                obj_priv->in_execbuffer = true;
+               flips += atomic_read(&obj_priv->pending_flip);
+       }
+
+       if (flips > 0) {
+               ret = i915_gem_wait_for_pending_flip(dev, object_list,
+                                                    args->buffer_count);
+               if (ret)
+                       goto err;
        }
 
        /* Pin and relocate */
@@ -4385,7 +4426,7 @@ i915_gem_init_hws(struct drm_device *dev)
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
        I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
        I915_READ(HWS_PGA); /* posting read */
-       DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
+       DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
 
        return 0;
 }
@@ -4643,8 +4684,8 @@ i915_gem_load(struct drm_device *dev)
                        for (i = 0; i < 8; i++)
                                I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
        }
-
        i915_gem_detect_bit_6_swizzle(dev);
+       init_waitqueue_head(&dev_priv->pending_flip_queue);
 }
 
 /*
@@ -4667,7 +4708,7 @@ int i915_gem_init_phys_object(struct drm_device *dev,
 
        phys_obj->id = id;
 
-       phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff);
+       phys_obj->handle = drm_pci_alloc(dev, size, 0);
        if (!phys_obj->handle) {
                ret = -ENOMEM;
                goto kfree_obj;
@@ -4819,7 +4860,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
        user_data = (char __user *) (uintptr_t) args->data_ptr;
        obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
 
-       DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size);
+       DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size);
        ret = copy_from_user(obj_addr, user_data, args->size);
        if (ret)
                return -EFAULT;