|  |  |  | @ -36,7 +36,8 @@ | 
		
	
		
			
				|  |  |  |  | #include <linux/pci.h> | 
		
	
		
			
				|  |  |  |  | #include <linux/intel-gtt.h> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | 
		
	
		
			
				|  |  |  |  | static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv); | 
		
	
		
			
				|  |  |  |  | static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 						  bool pipelined); | 
		
	
	
		
			
				
					
					|  |  |  | @ -51,7 +52,9 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o | 
		
	
		
			
				|  |  |  |  | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 					  bool interruptible); | 
		
	
		
			
				|  |  |  |  | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 				       unsigned alignment, bool mappable); | 
		
	
		
			
				|  |  |  |  | 				       unsigned alignment, | 
		
	
		
			
				|  |  |  |  | 				       bool mappable, | 
		
	
		
			
				|  |  |  |  | 				       bool need_fence); | 
		
	
		
			
				|  |  |  |  | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 
		
	
		
			
				|  |  |  |  | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 				struct drm_i915_gem_pwrite *args, | 
		
	
	
		
			
				
					
					|  |  |  | @ -79,30 +82,26 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  | 				  struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | 				  struct drm_i915_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.gtt_count++; | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.gtt_memory += obj->size; | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.gtt_memory += obj->gtt_space->size; | 
		
	
		
			
				|  |  |  |  | 	if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) { | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.mappable_gtt_used += | 
		
	
		
			
				|  |  |  |  | 			min_t(size_t, obj->size, | 
		
	
		
			
				|  |  |  |  | 			      dev_priv->mm.gtt_mappable_end | 
		
	
		
			
				|  |  |  |  | 					- obj_priv->gtt_offset); | 
		
	
		
			
				|  |  |  |  | 			min_t(size_t, obj->gtt_space->size, | 
		
	
		
			
				|  |  |  |  | 			      dev_priv->mm.gtt_mappable_end - obj->gtt_offset); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  | 				     struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | 				     struct drm_i915_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.gtt_count--; | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.gtt_memory -= obj->size; | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.gtt_memory -= obj->gtt_space->size; | 
		
	
		
			
				|  |  |  |  | 	if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) { | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.mappable_gtt_used -= | 
		
	
		
			
				|  |  |  |  | 			min_t(size_t, obj->size, | 
		
	
		
			
				|  |  |  |  | 			      dev_priv->mm.gtt_mappable_end | 
		
	
		
			
				|  |  |  |  | 					- obj_priv->gtt_offset); | 
		
	
		
			
				|  |  |  |  | 			min_t(size_t, obj->gtt_space->size, | 
		
	
		
			
				|  |  |  |  | 			      dev_priv->mm.gtt_mappable_end - obj->gtt_offset); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -113,47 +112,43 @@ static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | i915_gem_info_update_mappable(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  | 			      struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 			      struct drm_i915_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 			      bool mappable) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (mappable) { | 
		
	
		
			
				|  |  |  |  | 		if (obj_priv->pin_mappable && obj_priv->fault_mappable) | 
		
	
		
			
				|  |  |  |  | 		if (obj->pin_mappable && obj->fault_mappable) | 
		
	
		
			
				|  |  |  |  | 			/* Combined state was already mappable. */ | 
		
	
		
			
				|  |  |  |  | 			return; | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.gtt_mappable_count++; | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.gtt_mappable_memory += obj->size; | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.gtt_mappable_memory += obj->gtt_space->size; | 
		
	
		
			
				|  |  |  |  | 	} else { | 
		
	
		
			
				|  |  |  |  | 		if (obj_priv->pin_mappable || obj_priv->fault_mappable) | 
		
	
		
			
				|  |  |  |  | 		if (obj->pin_mappable || obj->fault_mappable) | 
		
	
		
			
				|  |  |  |  | 			/* Combined state still mappable. */ | 
		
	
		
			
				|  |  |  |  | 			return; | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.gtt_mappable_count--; | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.gtt_mappable_memory -= obj->size; | 
		
	
		
			
				|  |  |  |  | 		dev_priv->mm.gtt_mappable_memory -= obj->gtt_space->size; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  | 				  struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 				  struct drm_i915_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 				  bool mappable) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.pin_count++; | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.pin_memory += obj->size; | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.pin_memory += obj->gtt_space->size; | 
		
	
		
			
				|  |  |  |  | 	if (mappable) { | 
		
	
		
			
				|  |  |  |  | 		obj_priv->pin_mappable = true; | 
		
	
		
			
				|  |  |  |  | 		obj->pin_mappable = true; | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_update_mappable(dev_priv, obj, true); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, | 
		
	
		
			
				|  |  |  |  | 				     struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | 				     struct drm_i915_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.pin_count--; | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.pin_memory -= obj->size; | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->pin_mappable) { | 
		
	
		
			
				|  |  |  |  | 		obj_priv->pin_mappable = false; | 
		
	
		
			
				|  |  |  |  | 	dev_priv->mm.pin_memory -= obj->gtt_space->size; | 
		
	
		
			
				|  |  |  |  | 	if (obj->pin_mappable) { | 
		
	
		
			
				|  |  |  |  | 		obj->pin_mappable = false; | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_update_mappable(dev_priv, obj, false); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @ -309,16 +304,6 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | 
		
	
		
			
				|  |  |  |  | 	return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static bool | 
		
	
		
			
				|  |  |  |  | i915_gem_object_cpu_accessible(struct drm_i915_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->base.dev; | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return obj->gtt_space == NULL || | 
		
	
		
			
				|  |  |  |  | 		obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = obj->dev->dev_private; | 
		
	
	
		
			
				
					
					|  |  |  | @ -1083,7 +1068,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | 
		
	
		
			
				|  |  |  |  | 	else if (obj_priv->tiling_mode == I915_TILING_NONE && | 
		
	
		
			
				|  |  |  |  | 		 obj_priv->gtt_space && | 
		
	
		
			
				|  |  |  |  | 		 obj->write_domain != I915_GEM_DOMAIN_CPU) { | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_pin(obj, 0, true); | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_pin(obj, 0, true, false); | 
		
	
		
			
				|  |  |  |  | 		if (ret) | 
		
	
		
			
				|  |  |  |  | 			goto out; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -1307,11 +1292,19 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 
		
	
		
			
				|  |  |  |  | 	/* Now bind it into the GTT if needed */ | 
		
	
		
			
				|  |  |  |  | 	mutex_lock(&dev->struct_mutex); | 
		
	
		
			
				|  |  |  |  | 	BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable); | 
		
	
		
			
				|  |  |  |  | 	if (!i915_gem_object_cpu_accessible(obj_priv)) | 
		
	
		
			
				|  |  |  |  | 		i915_gem_object_unbind(obj); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->gtt_space) { | 
		
	
		
			
				|  |  |  |  | 		if (!obj_priv->mappable || | 
		
	
		
			
				|  |  |  |  | 		    (obj_priv->tiling_mode && !obj_priv->fenceable)) { | 
		
	
		
			
				|  |  |  |  | 			ret = i915_gem_object_unbind(obj); | 
		
	
		
			
				|  |  |  |  | 			if (ret) | 
		
	
		
			
				|  |  |  |  | 				goto unlock; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (!obj_priv->gtt_space) { | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_bind_to_gtt(obj, 0, true); | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_bind_to_gtt(obj, 0, | 
		
	
		
			
				|  |  |  |  | 						  true, obj_priv->tiling_mode); | 
		
	
		
			
				|  |  |  |  | 		if (ret) | 
		
	
		
			
				|  |  |  |  | 			goto unlock; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
	
		
			
				
					
					|  |  |  | @ -1322,7 +1315,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (!obj_priv->fault_mappable) { | 
		
	
		
			
				|  |  |  |  | 		obj_priv->fault_mappable = true; | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_update_mappable(dev_priv, obj, true); | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_update_mappable(dev_priv, obj_priv, true); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Need a new fence register? */ | 
		
	
	
		
			
				
					
					|  |  |  | @ -1448,7 +1441,7 @@ i915_gem_release_mmap(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->fault_mappable) { | 
		
	
		
			
				|  |  |  |  | 		obj_priv->fault_mappable = false; | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_update_mappable(dev_priv, obj, false); | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_update_mappable(dev_priv, obj_priv, false); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -1473,32 +1466,51 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  |  * potential fence register mapping if needed. | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | static uint32_t | 
		
	
		
			
				|  |  |  |  | i915_gem_get_gtt_alignment(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	int start, i; | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj_priv->base.dev; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/*
 | 
		
	
		
			
				|  |  |  |  | 	 * Minimum alignment is 4k (GTT page size), but might be greater | 
		
	
		
			
				|  |  |  |  | 	 * if a fence register is needed for the object. | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	if (INTEL_INFO(dev)->gen >= 4 || obj_priv->tiling_mode == I915_TILING_NONE) | 
		
	
		
			
				|  |  |  |  | 	if (INTEL_INFO(dev)->gen >= 4 || | 
		
	
		
			
				|  |  |  |  | 	    obj_priv->tiling_mode == I915_TILING_NONE) | 
		
	
		
			
				|  |  |  |  | 		return 4096; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/*
 | 
		
	
		
			
				|  |  |  |  | 	 * Previous chips need to be aligned to the size of the smallest | 
		
	
		
			
				|  |  |  |  | 	 * fence register that can contain the object. | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	return i915_gem_get_gtt_size(obj_priv); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static uint32_t | 
		
	
		
			
				|  |  |  |  | i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj_priv->base.dev; | 
		
	
		
			
				|  |  |  |  | 	uint32_t size; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/*
 | 
		
	
		
			
				|  |  |  |  | 	 * Minimum alignment is 4k (GTT page size), but might be greater | 
		
	
		
			
				|  |  |  |  | 	 * if a fence register is needed for the object. | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	if (INTEL_INFO(dev)->gen >= 4) | 
		
	
		
			
				|  |  |  |  | 		return obj_priv->base.size; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/*
 | 
		
	
		
			
				|  |  |  |  | 	 * Previous chips need to be aligned to the size of the smallest | 
		
	
		
			
				|  |  |  |  | 	 * fence register that can contain the object. | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	if (INTEL_INFO(dev)->gen == 3) | 
		
	
		
			
				|  |  |  |  | 		start = 1024*1024; | 
		
	
		
			
				|  |  |  |  | 		size = 1024*1024; | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 		start = 512*1024; | 
		
	
		
			
				|  |  |  |  | 		size = 512*1024; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	for (i = start; i < obj->size; i <<= 1) | 
		
	
		
			
				|  |  |  |  | 		; | 
		
	
		
			
				|  |  |  |  | 	while (size < obj_priv->base.size) | 
		
	
		
			
				|  |  |  |  | 		size <<= 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return i; | 
		
	
		
			
				|  |  |  |  | 	return size; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /**
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -2253,8 +2265,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	i915_gem_object_put_pages_gtt(obj); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	i915_gem_info_remove_gtt(dev_priv, obj); | 
		
	
		
			
				|  |  |  |  | 	i915_gem_info_remove_gtt(dev_priv, obj_priv); | 
		
	
		
			
				|  |  |  |  | 	list_del_init(&obj_priv->mm_list); | 
		
	
		
			
				|  |  |  |  | 	obj_priv->fenceable = true; | 
		
	
		
			
				|  |  |  |  | 	obj_priv->mappable = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	drm_mm_put_block(obj_priv->gtt_space); | 
		
	
		
			
				|  |  |  |  | 	obj_priv->gtt_space = NULL; | 
		
	
	
		
			
				
					
					|  |  |  | @ -2311,16 +2325,16 @@ i915_gpu_idle(struct drm_device *dev) | 
		
	
		
			
				|  |  |  |  | 	return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | static void sandybridge_write_fence_reg(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_gem_object *obj = reg->obj; | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	u32 size = i915_gem_get_gtt_size(obj_priv); | 
		
	
		
			
				|  |  |  |  | 	int regnum = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 	uint64_t val; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & | 
		
	
		
			
				|  |  |  |  | 	val = (uint64_t)((obj_priv->gtt_offset + size - 4096) & | 
		
	
		
			
				|  |  |  |  | 		    0xfffff000) << 32; | 
		
	
		
			
				|  |  |  |  | 	val |= obj_priv->gtt_offset & 0xfffff000; | 
		
	
		
			
				|  |  |  |  | 	val |= (uint64_t)((obj_priv->stride / 128) - 1) << | 
		
	
	
		
			
				
					
					|  |  |  | @ -2333,16 +2347,16 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | 	I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | static void i965_write_fence_reg(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_gem_object *obj = reg->obj; | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	u32 size = i915_gem_get_gtt_size(obj_priv); | 
		
	
		
			
				|  |  |  |  | 	int regnum = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 	uint64_t val; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & | 
		
	
		
			
				|  |  |  |  | 	val = (uint64_t)((obj_priv->gtt_offset + size - 4096) & | 
		
	
		
			
				|  |  |  |  | 		    0xfffff000) << 32; | 
		
	
		
			
				|  |  |  |  | 	val |= obj_priv->gtt_offset & 0xfffff000; | 
		
	
		
			
				|  |  |  |  | 	val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; | 
		
	
	
		
			
				
					
					|  |  |  | @ -2353,21 +2367,20 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | 	I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | static void i915_write_fence_reg(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_gem_object *obj = reg->obj; | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	int regnum = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 	u32 size = i915_gem_get_gtt_size(obj_priv); | 
		
	
		
			
				|  |  |  |  | 	uint32_t fence_reg, val, pitch_val; | 
		
	
		
			
				|  |  |  |  | 	int tile_width; | 
		
	
		
			
				|  |  |  |  | 	uint32_t fence_reg, val; | 
		
	
		
			
				|  |  |  |  | 	uint32_t pitch_val; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || | 
		
	
		
			
				|  |  |  |  | 	    (obj_priv->gtt_offset & (obj->size - 1))) { | 
		
	
		
			
				|  |  |  |  | 		WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n", | 
		
	
		
			
				|  |  |  |  | 		     __func__, obj_priv->gtt_offset, obj->size); | 
		
	
		
			
				|  |  |  |  | 	    (obj_priv->gtt_offset & (size - 1))) { | 
		
	
		
			
				|  |  |  |  | 		WARN(1, "%s: object 0x%08x [fenceable? %d] not 1M or size (0x%08x) aligned [gtt_space offset=%lx, size=%lx]\n", | 
		
	
		
			
				|  |  |  |  | 		     __func__, obj_priv->gtt_offset, obj_priv->fenceable, size, | 
		
	
		
			
				|  |  |  |  | 		     obj_priv->gtt_space->start, obj_priv->gtt_space->size); | 
		
	
		
			
				|  |  |  |  | 		return; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -2390,23 +2403,24 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | 	val = obj_priv->gtt_offset; | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->tiling_mode == I915_TILING_Y) | 
		
	
		
			
				|  |  |  |  | 		val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 
		
	
		
			
				|  |  |  |  | 	val |= I915_FENCE_SIZE_BITS(obj->size); | 
		
	
		
			
				|  |  |  |  | 	val |= I915_FENCE_SIZE_BITS(size); | 
		
	
		
			
				|  |  |  |  | 	val |= pitch_val << I830_FENCE_PITCH_SHIFT; | 
		
	
		
			
				|  |  |  |  | 	val |= I830_FENCE_REG_VALID; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (regnum < 8) | 
		
	
		
			
				|  |  |  |  | 		fence_reg = FENCE_REG_830_0 + (regnum * 4); | 
		
	
		
			
				|  |  |  |  | 	fence_reg = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 	if (fence_reg < 8) | 
		
	
		
			
				|  |  |  |  | 		fence_reg = FENCE_REG_830_0 + fence_reg * 4; | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 		fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4); | 
		
	
		
			
				|  |  |  |  | 		fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; | 
		
	
		
			
				|  |  |  |  | 	I915_WRITE(fence_reg, val); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | static void i830_write_fence_reg(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_gem_object *obj = reg->obj; | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	u32 size = i915_gem_get_gtt_size(obj_priv); | 
		
	
		
			
				|  |  |  |  | 	int regnum = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 	uint32_t val; | 
		
	
		
			
				|  |  |  |  | 	uint32_t pitch_val; | 
		
	
	
		
			
				
					
					|  |  |  | @ -2426,7 +2440,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | 	val = obj_priv->gtt_offset; | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->tiling_mode == I915_TILING_Y) | 
		
	
		
			
				|  |  |  |  | 		val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 
		
	
		
			
				|  |  |  |  | 	fence_size_bits = I830_FENCE_SIZE_BITS(obj->size); | 
		
	
		
			
				|  |  |  |  | 	fence_size_bits = I830_FENCE_SIZE_BITS(size); | 
		
	
		
			
				|  |  |  |  | 	WARN_ON(fence_size_bits & ~0x00000f00); | 
		
	
		
			
				|  |  |  |  | 	val |= fence_size_bits; | 
		
	
		
			
				|  |  |  |  | 	val |= pitch_val << I830_FENCE_PITCH_SHIFT; | 
		
	
	
		
			
				
					
					|  |  |  | @ -2438,10 +2452,9 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | 
		
	
		
			
				|  |  |  |  | static int i915_find_fence_reg(struct drm_device *dev, | 
		
	
		
			
				|  |  |  |  | 			       bool interruptible) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_fence_reg *reg = NULL; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = NULL; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_private *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 	struct drm_gem_object *obj = NULL; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_fence_reg *reg; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = NULL; | 
		
	
		
			
				|  |  |  |  | 	int i, avail, ret; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* First try to find a free reg */ | 
		
	
	
		
			
				
					
					|  |  |  | @ -2460,33 +2473,31 @@ static int i915_find_fence_reg(struct drm_device *dev, | 
		
	
		
			
				|  |  |  |  | 		return -ENOSPC; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* None available, try to steal one or wait for a user to finish */ | 
		
	
		
			
				|  |  |  |  | 	i = I915_FENCE_REG_NONE; | 
		
	
		
			
				|  |  |  |  | 	avail = I915_FENCE_REG_NONE; | 
		
	
		
			
				|  |  |  |  | 	list_for_each_entry(reg, &dev_priv->mm.fence_list, | 
		
	
		
			
				|  |  |  |  | 			    lru_list) { | 
		
	
		
			
				|  |  |  |  | 		obj = reg->obj; | 
		
	
		
			
				|  |  |  |  | 		obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		obj_priv = to_intel_bo(reg->obj); | 
		
	
		
			
				|  |  |  |  | 		if (obj_priv->pin_count) | 
		
	
		
			
				|  |  |  |  | 			continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		/* found one! */ | 
		
	
		
			
				|  |  |  |  | 		i = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 		avail = obj_priv->fence_reg; | 
		
	
		
			
				|  |  |  |  | 		break; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	BUG_ON(i == I915_FENCE_REG_NONE); | 
		
	
		
			
				|  |  |  |  | 	BUG_ON(avail == I915_FENCE_REG_NONE); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* We only have a reference on obj from the active list. put_fence_reg
 | 
		
	
		
			
				|  |  |  |  | 	 * might drop that one, causing a use-after-free in it. So hold a | 
		
	
		
			
				|  |  |  |  | 	 * private reference to obj like the other callers of put_fence_reg | 
		
	
		
			
				|  |  |  |  | 	 * (set_tiling ioctl) do. */ | 
		
	
		
			
				|  |  |  |  | 	drm_gem_object_reference(obj); | 
		
	
		
			
				|  |  |  |  | 	ret = i915_gem_object_put_fence_reg(obj, interruptible); | 
		
	
		
			
				|  |  |  |  | 	drm_gem_object_unreference(obj); | 
		
	
		
			
				|  |  |  |  | 	drm_gem_object_reference(&obj_priv->base); | 
		
	
		
			
				|  |  |  |  | 	ret = i915_gem_object_put_fence_reg(&obj_priv->base, interruptible); | 
		
	
		
			
				|  |  |  |  | 	drm_gem_object_unreference(&obj_priv->base); | 
		
	
		
			
				|  |  |  |  | 	if (ret != 0) | 
		
	
		
			
				|  |  |  |  | 		return ret; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return i; | 
		
	
		
			
				|  |  |  |  | 	return avail; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /**
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -2551,22 +2562,23 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	switch (INTEL_INFO(dev)->gen) { | 
		
	
		
			
				|  |  |  |  | 	case 6: | 
		
	
		
			
				|  |  |  |  | 		sandybridge_write_fence_reg(reg); | 
		
	
		
			
				|  |  |  |  | 		sandybridge_write_fence_reg(obj); | 
		
	
		
			
				|  |  |  |  | 		break; | 
		
	
		
			
				|  |  |  |  | 	case 5: | 
		
	
		
			
				|  |  |  |  | 	case 4: | 
		
	
		
			
				|  |  |  |  | 		i965_write_fence_reg(reg); | 
		
	
		
			
				|  |  |  |  | 		i965_write_fence_reg(obj); | 
		
	
		
			
				|  |  |  |  | 		break; | 
		
	
		
			
				|  |  |  |  | 	case 3: | 
		
	
		
			
				|  |  |  |  | 		i915_write_fence_reg(reg); | 
		
	
		
			
				|  |  |  |  | 		i915_write_fence_reg(obj); | 
		
	
		
			
				|  |  |  |  | 		break; | 
		
	
		
			
				|  |  |  |  | 	case 2: | 
		
	
		
			
				|  |  |  |  | 		i830_write_fence_reg(reg); | 
		
	
		
			
				|  |  |  |  | 		i830_write_fence_reg(obj); | 
		
	
		
			
				|  |  |  |  | 		break; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, | 
		
	
		
			
				|  |  |  |  | 			obj_priv->tiling_mode); | 
		
	
		
			
				|  |  |  |  | 	trace_i915_gem_object_get_fence(obj, | 
		
	
		
			
				|  |  |  |  | 					obj_priv->fence_reg, | 
		
	
		
			
				|  |  |  |  | 					obj_priv->tiling_mode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @ -2671,13 +2683,15 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | static int | 
		
	
		
			
				|  |  |  |  | i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 			    unsigned alignment, | 
		
	
		
			
				|  |  |  |  | 			    bool mappable) | 
		
	
		
			
				|  |  |  |  | 			    bool mappable, | 
		
	
		
			
				|  |  |  |  | 			    bool need_fence) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	drm_i915_private_t *dev_priv = dev->dev_private; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	struct drm_mm_node *free_space; | 
		
	
		
			
				|  |  |  |  | 	gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN; | 
		
	
		
			
				|  |  |  |  | 	gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; | 
		
	
		
			
				|  |  |  |  | 	u32 size, fence_size, fence_alignment; | 
		
	
		
			
				|  |  |  |  | 	int ret; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->madv != I915_MADV_WILLNEED) { | 
		
	
	
		
			
				
					
					|  |  |  | @ -2685,13 +2699,18 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 		return -EINVAL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	fence_size = i915_gem_get_gtt_size(obj_priv); | 
		
	
		
			
				|  |  |  |  | 	fence_alignment = i915_gem_get_gtt_alignment(obj_priv); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (alignment == 0) | 
		
	
		
			
				|  |  |  |  | 		alignment = i915_gem_get_gtt_alignment(obj); | 
		
	
		
			
				|  |  |  |  | 	if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { | 
		
	
		
			
				|  |  |  |  | 		alignment = need_fence ? fence_alignment : 4096; | 
		
	
		
			
				|  |  |  |  | 	if (need_fence && alignment & (fence_alignment - 1)) { | 
		
	
		
			
				|  |  |  |  | 		DRM_ERROR("Invalid object alignment requested %u\n", alignment); | 
		
	
		
			
				|  |  |  |  | 		return -EINVAL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	size = need_fence ? fence_size : obj->size; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* If the object is bigger than the entire aperture, reject it early
 | 
		
	
		
			
				|  |  |  |  | 	 * before evicting everything in a vain attempt to find space. | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
	
		
			
				
					
					|  |  |  | @ -2705,32 +2724,29 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 	if (mappable) | 
		
	
		
			
				|  |  |  |  | 		free_space = | 
		
	
		
			
				|  |  |  |  | 			drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, | 
		
	
		
			
				|  |  |  |  | 						    obj->size, alignment, 0, | 
		
	
		
			
				|  |  |  |  | 						    size, alignment, 0, | 
		
	
		
			
				|  |  |  |  | 						    dev_priv->mm.gtt_mappable_end, | 
		
	
		
			
				|  |  |  |  | 						    0); | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 		free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, | 
		
	
		
			
				|  |  |  |  | 						obj->size, alignment, 0); | 
		
	
		
			
				|  |  |  |  | 						size, alignment, 0); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (free_space != NULL) { | 
		
	
		
			
				|  |  |  |  | 		if (mappable) | 
		
	
		
			
				|  |  |  |  | 			obj_priv->gtt_space = | 
		
	
		
			
				|  |  |  |  | 				drm_mm_get_block_range_generic(free_space, | 
		
	
		
			
				|  |  |  |  | 							       obj->size, | 
		
	
		
			
				|  |  |  |  | 							       alignment, 0, | 
		
	
		
			
				|  |  |  |  | 							       size, alignment, 0, | 
		
	
		
			
				|  |  |  |  | 							       dev_priv->mm.gtt_mappable_end, | 
		
	
		
			
				|  |  |  |  | 							       0); | 
		
	
		
			
				|  |  |  |  | 		else | 
		
	
		
			
				|  |  |  |  | 			obj_priv->gtt_space = | 
		
	
		
			
				|  |  |  |  | 				drm_mm_get_block(free_space, obj->size, | 
		
	
		
			
				|  |  |  |  | 						 alignment); | 
		
	
		
			
				|  |  |  |  | 				drm_mm_get_block(free_space, size, alignment); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->gtt_space == NULL) { | 
		
	
		
			
				|  |  |  |  | 		/* If the gtt is empty and we're still having trouble
 | 
		
	
		
			
				|  |  |  |  | 		 * fitting our object in, we're out of memory. | 
		
	
		
			
				|  |  |  |  | 		 */ | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_evict_something(dev, obj->size, alignment, | 
		
	
		
			
				|  |  |  |  | 					       mappable); | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_evict_something(dev, size, alignment, mappable); | 
		
	
		
			
				|  |  |  |  | 		if (ret) | 
		
	
		
			
				|  |  |  |  | 			return ret; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -2744,7 +2760,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		if (ret == -ENOMEM) { | 
		
	
		
			
				|  |  |  |  | 			/* first try to clear up some space from the GTT */ | 
		
	
		
			
				|  |  |  |  | 			ret = i915_gem_evict_something(dev, obj->size, | 
		
	
		
			
				|  |  |  |  | 			ret = i915_gem_evict_something(dev, size, | 
		
	
		
			
				|  |  |  |  | 						       alignment, mappable); | 
		
	
		
			
				|  |  |  |  | 			if (ret) { | 
		
	
		
			
				|  |  |  |  | 				/* now try to shrink everyone else */ | 
		
	
	
		
			
				
					
					|  |  |  | @ -2775,8 +2791,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 		drm_mm_put_block(obj_priv->gtt_space); | 
		
	
		
			
				|  |  |  |  | 		obj_priv->gtt_space = NULL; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_evict_something(dev, obj->size, alignment, | 
		
	
		
			
				|  |  |  |  | 					       mappable); | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_evict_something(dev, size, | 
		
	
		
			
				|  |  |  |  | 					       alignment, mappable); | 
		
	
		
			
				|  |  |  |  | 		if (ret) | 
		
	
		
			
				|  |  |  |  | 			return ret; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -2787,7 +2803,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* keep track of bounds object by adding it to the inactive list */ | 
		
	
		
			
				|  |  |  |  | 	list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); | 
		
	
		
			
				|  |  |  |  | 	i915_gem_info_add_gtt(dev_priv, obj); | 
		
	
		
			
				|  |  |  |  | 	i915_gem_info_add_gtt(dev_priv, obj_priv); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/* Assert that the object is not currently in any GPU domain. As it
 | 
		
	
		
			
				|  |  |  |  | 	 * wasn't in the GTT, there shouldn't be any way it could have been in | 
		
	
	
		
			
				
					
					|  |  |  | @ -2798,6 +2814,13 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	obj_priv->fenceable = | 
		
	
		
			
				|  |  |  |  | 		obj_priv->gtt_space->size == fence_size && | 
		
	
		
			
				|  |  |  |  | 		(obj_priv->gtt_space->start & (fence_alignment -1)) == 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	obj_priv->mappable = | 
		
	
		
			
				|  |  |  |  | 		obj_priv->gtt_offset + obj->size <= dev_priv->mm.gtt_mappable_end; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -3516,9 +3539,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, | 
		
	
		
			
				|  |  |  |  | 				entry->relocation_count ? true : need_fence; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 			/* Check fence reg constraints and rebind if necessary */ | 
		
	
		
			
				|  |  |  |  | 			if (need_fence && | 
		
	
		
			
				|  |  |  |  | 			    !i915_gem_object_fence_offset_ok(&obj->base, | 
		
	
		
			
				|  |  |  |  | 							     obj->tiling_mode)) { | 
		
	
		
			
				|  |  |  |  | 			if ((need_fence && !obj->fenceable) || | 
		
	
		
			
				|  |  |  |  | 			    (need_mappable && !obj->mappable)) { | 
		
	
		
			
				|  |  |  |  | 				ret = i915_gem_object_unbind(&obj->base); | 
		
	
		
			
				|  |  |  |  | 				if (ret) | 
		
	
		
			
				|  |  |  |  | 					break; | 
		
	
	
		
			
				
					
					|  |  |  | @ -3526,7 +3548,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 			ret = i915_gem_object_pin(&obj->base, | 
		
	
		
			
				|  |  |  |  | 						  entry->alignment, | 
		
	
		
			
				|  |  |  |  | 						  need_mappable); | 
		
	
		
			
				|  |  |  |  | 						  need_mappable, | 
		
	
		
			
				|  |  |  |  | 						  need_fence); | 
		
	
		
			
				|  |  |  |  | 			if (ret) | 
		
	
		
			
				|  |  |  |  | 				break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -4097,7 +4120,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | int | 
		
	
		
			
				|  |  |  |  | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, | 
		
	
		
			
				|  |  |  |  | 		    bool mappable) | 
		
	
		
			
				|  |  |  |  | 		    bool mappable, bool need_fence) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	struct drm_device *dev = obj->dev; | 
		
	
		
			
				|  |  |  |  | 	struct drm_i915_private *dev_priv = dev->dev_private; | 
		
	
	
		
			
				
					
					|  |  |  | @ -4108,14 +4131,15 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, | 
		
	
		
			
				|  |  |  |  | 	WARN_ON(i915_verify_lists(dev)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->gtt_space != NULL) { | 
		
	
		
			
				|  |  |  |  | 		if (alignment == 0) | 
		
	
		
			
				|  |  |  |  | 			alignment = i915_gem_get_gtt_alignment(obj); | 
		
	
		
			
				|  |  |  |  | 		if (obj_priv->gtt_offset & (alignment - 1) || | 
		
	
		
			
				|  |  |  |  | 		    (mappable && !i915_gem_object_cpu_accessible(obj_priv))) { | 
		
	
		
			
				|  |  |  |  | 		if ((alignment && obj_priv->gtt_offset & (alignment - 1)) || | 
		
	
		
			
				|  |  |  |  | 		    (need_fence && !obj_priv->fenceable) || | 
		
	
		
			
				|  |  |  |  | 		    (mappable && !obj_priv->mappable)) { | 
		
	
		
			
				|  |  |  |  | 			WARN(obj_priv->pin_count, | 
		
	
		
			
				|  |  |  |  | 			     "bo is already pinned with incorrect alignment:" | 
		
	
		
			
				|  |  |  |  | 			     " offset=%x, req.alignment=%x\n", | 
		
	
		
			
				|  |  |  |  | 			     obj_priv->gtt_offset, alignment); | 
		
	
		
			
				|  |  |  |  | 			     " offset=%x, req.alignment=%x, need_fence=%d, fenceable=%d, mappable=%d, cpu_accessible=%d\n", | 
		
	
		
			
				|  |  |  |  | 			     obj_priv->gtt_offset, alignment, | 
		
	
		
			
				|  |  |  |  | 			     need_fence, obj_priv->fenceable, | 
		
	
		
			
				|  |  |  |  | 			     mappable, obj_priv->mappable); | 
		
	
		
			
				|  |  |  |  | 			ret = i915_gem_object_unbind(obj); | 
		
	
		
			
				|  |  |  |  | 			if (ret) | 
		
	
		
			
				|  |  |  |  | 				return ret; | 
		
	
	
		
			
				
					
					|  |  |  | @ -4123,13 +4147,14 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->gtt_space == NULL) { | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_bind_to_gtt(obj, alignment, mappable); | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_bind_to_gtt(obj, alignment, | 
		
	
		
			
				|  |  |  |  | 						  mappable, need_fence); | 
		
	
		
			
				|  |  |  |  | 		if (ret) | 
		
	
		
			
				|  |  |  |  | 			return ret; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->pin_count++ == 0) { | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_add_pin(dev_priv, obj, mappable); | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_add_pin(dev_priv, obj_priv, mappable); | 
		
	
		
			
				|  |  |  |  | 		if (!obj_priv->active) | 
		
	
		
			
				|  |  |  |  | 			list_move_tail(&obj_priv->mm_list, | 
		
	
		
			
				|  |  |  |  | 				       &dev_priv->mm.pinned_list); | 
		
	
	
		
			
				
					
					|  |  |  | @ -4155,7 +4180,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) | 
		
	
		
			
				|  |  |  |  | 		if (!obj_priv->active) | 
		
	
		
			
				|  |  |  |  | 			list_move_tail(&obj_priv->mm_list, | 
		
	
		
			
				|  |  |  |  | 				       &dev_priv->mm.inactive_list); | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_remove_pin(dev_priv, obj); | 
		
	
		
			
				|  |  |  |  | 		i915_gem_info_remove_pin(dev_priv, obj_priv); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	WARN_ON(i915_verify_lists(dev)); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @ -4196,7 +4221,8 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, | 
		
	
		
			
				|  |  |  |  | 	obj_priv->user_pin_count++; | 
		
	
		
			
				|  |  |  |  | 	obj_priv->pin_filp = file_priv; | 
		
	
		
			
				|  |  |  |  | 	if (obj_priv->user_pin_count == 1) { | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_pin(obj, args->alignment, true); | 
		
	
		
			
				|  |  |  |  | 		ret = i915_gem_object_pin(obj, args->alignment, | 
		
	
		
			
				|  |  |  |  | 					  true, obj_priv->tiling_mode); | 
		
	
		
			
				|  |  |  |  | 		if (ret) | 
		
	
		
			
				|  |  |  |  | 			goto out; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
	
		
			
				
					
					|  |  |  | @ -4389,6 +4415,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | 
		
	
		
			
				|  |  |  |  | 	INIT_LIST_HEAD(&obj->ring_list); | 
		
	
		
			
				|  |  |  |  | 	INIT_LIST_HEAD(&obj->gpu_write_list); | 
		
	
		
			
				|  |  |  |  | 	obj->madv = I915_MADV_WILLNEED; | 
		
	
		
			
				|  |  |  |  | 	obj->fenceable = true; | 
		
	
		
			
				|  |  |  |  | 	obj->mappable = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	return &obj->base; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @ -4508,7 +4536,7 @@ i915_gem_init_pipe_control(struct drm_device *dev) | 
		
	
		
			
				|  |  |  |  | 	obj_priv = to_intel_bo(obj); | 
		
	
		
			
				|  |  |  |  | 	obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	ret = i915_gem_object_pin(obj, 4096, true); | 
		
	
		
			
				|  |  |  |  | 	ret = i915_gem_object_pin(obj, 4096, true, false); | 
		
	
		
			
				|  |  |  |  | 	if (ret) | 
		
	
		
			
				|  |  |  |  | 		goto err_unref; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | 
 |