drm/i915: handle walking compact dma scatter lists
[deliverable/linux.git] / drivers / gpu / drm / i915 / i915_gem.c
index 8413ffced81573c0144aafeac992218755b71cc9..5cf6140354dbd62586f0cfc4fcdc20b3eee26e2f 100644 (file)
@@ -411,10 +411,9 @@ i915_gem_shmem_pread(struct drm_device *dev,
        int obj_do_bit17_swizzling, page_do_bit17_swizzling;
        int prefaulted = 0;
        int needs_clflush = 0;
-       struct scatterlist *sg;
-       int i;
+       struct sg_page_iter sg_iter;
 
-       user_data = (char __user *) (uintptr_t) args->data_ptr;
+       user_data = to_user_ptr(args->data_ptr);
        remain = args->size;
 
        obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
@@ -441,11 +440,9 @@ i915_gem_shmem_pread(struct drm_device *dev,
 
        offset = args->offset;
 
-       for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) {
-               struct page *page;
-
-               if (i < offset >> PAGE_SHIFT)
-                       continue;
+       for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
+                        offset >> PAGE_SHIFT) {
+               struct page *page = sg_iter.page;
 
                if (remain <= 0)
                        break;
@@ -460,7 +457,6 @@ i915_gem_shmem_pread(struct drm_device *dev,
                if ((shmem_page_offset + page_length) > PAGE_SIZE)
                        page_length = PAGE_SIZE - shmem_page_offset;
 
-               page = sg_page(sg);
                page_do_bit17_swizzling = obj_do_bit17_swizzling &&
                        (page_to_phys(page) & (1 << 17)) != 0;
 
@@ -522,7 +518,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
                return 0;
 
        if (!access_ok(VERIFY_WRITE,
-                      (char __user *)(uintptr_t)args->data_ptr,
+                      to_user_ptr(args->data_ptr),
                       args->size))
                return -EFAULT;
 
@@ -613,7 +609,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
        if (ret)
                goto out_unpin;
 
-       user_data = (char __user *) (uintptr_t) args->data_ptr;
+       user_data = to_user_ptr(args->data_ptr);
        remain = args->size;
 
        offset = obj->gtt_offset + args->offset;
@@ -732,10 +728,9 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
        int hit_slowpath = 0;
        int needs_clflush_after = 0;
        int needs_clflush_before = 0;
-       int i;
-       struct scatterlist *sg;
+       struct sg_page_iter sg_iter;
 
-       user_data = (char __user *) (uintptr_t) args->data_ptr;
+       user_data = to_user_ptr(args->data_ptr);
        remain = args->size;
 
        obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
@@ -768,13 +763,11 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
        offset = args->offset;
        obj->dirty = 1;
 
-       for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) {
-               struct page *page;
+       for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
+                        offset >> PAGE_SHIFT) {
+               struct page *page = sg_iter.page;
                int partial_cacheline_write;
 
-               if (i < offset >> PAGE_SHIFT)
-                       continue;
-
                if (remain <= 0)
                        break;
 
@@ -796,7 +789,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
                        ((shmem_page_offset | page_length)
                                & (boot_cpu_data.x86_clflush_size - 1));
 
-               page = sg_page(sg);
                page_do_bit17_swizzling = obj_do_bit17_swizzling &&
                        (page_to_phys(page) & (1 << 17)) != 0;
 
@@ -867,11 +859,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
                return 0;
 
        if (!access_ok(VERIFY_READ,
-                      (char __user *)(uintptr_t)args->data_ptr,
+                      to_user_ptr(args->data_ptr),
                       args->size))
                return -EFAULT;
 
-       ret = fault_in_multipages_readable((char __user *)(uintptr_t)args->data_ptr,
+       ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr),
                                           args->size);
        if (ret)
                return -EFAULT;
@@ -1618,7 +1610,7 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
         * To do this we must instruct the shmfs to drop all of its
         * backing pages, *now*.
         */
-       inode = obj->base.filp->f_path.dentry->d_inode;
+       inode = file_inode(obj->base.filp);
        shmem_truncate_range(inode, 0, (loff_t)-1);
 
        obj->madv = __I915_MADV_PURGED;
@@ -1783,7 +1775,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
         *
         * Fail silently without starting the shrinker
         */
-       mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+       mapping = file_inode(obj->base.filp)->i_mapping;
        gfp = mapping_gfp_mask(mapping);
        gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
        gfp &= ~(__GFP_IO | __GFP_WAIT);
@@ -3747,7 +3739,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
                mask |= __GFP_DMA32;
        }
 
-       mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+       mapping = file_inode(obj->base.filp)->i_mapping;
        mapping_set_gfp_mask(mapping, mask);
 
        i915_gem_object_init(obj, &i915_gem_object_ops);
@@ -4010,7 +4002,16 @@ int i915_gem_init(struct drm_device *dev)
        int ret;
 
        mutex_lock(&dev->struct_mutex);
+
+       if (IS_VALLEYVIEW(dev)) {
+               /* VLVA0 (potential hack), BIOS isn't actually waking us */
+               I915_WRITE(VLV_GTLC_WAKE_CTRL, 1);
+               if (wait_for((I915_READ(VLV_GTLC_PW_STATUS) & 1) == 1, 10))
+                       DRM_DEBUG_DRIVER("allow wake ack timed out\n");
+       }
+
        i915_gem_init_global_gtt(dev);
+
        ret = i915_gem_init_hw(dev);
        mutex_unlock(&dev->struct_mutex);
        if (ret) {
@@ -4232,7 +4233,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev)
 void i915_gem_detach_phys_object(struct drm_device *dev,
                                 struct drm_i915_gem_object *obj)
 {
-       struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+       struct address_space *mapping = file_inode(obj->base.filp)->i_mapping;
        char *vaddr;
        int i;
        int page_count;
@@ -4268,7 +4269,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
                            int id,
                            int align)
 {
-       struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+       struct address_space *mapping = file_inode(obj->base.filp)->i_mapping;
        drm_i915_private_t *dev_priv = dev->dev_private;
        int ret = 0;
        int page_count;
@@ -4327,7 +4328,7 @@ i915_gem_phys_pwrite(struct drm_device *dev,
                     struct drm_file *file_priv)
 {
        void *vaddr = obj->phys_obj->handle->vaddr + args->offset;
-       char __user *user_data = (char __user *) (uintptr_t) args->data_ptr;
+       char __user *user_data = to_user_ptr(args->data_ptr);
 
        if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
                unsigned long unwritten;
This page took 0.032956 seconds and 5 git commands to generate.