diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/drm_bo_move.c | 4 | ||||
| -rw-r--r-- | linux-core/drm_mm.c | 1 | ||||
| -rw-r--r-- | linux-core/drm_ttm.c | 1 | ||||
| -rw-r--r-- | linux-core/i915_buffer.c | 82 | ||||
| -rw-r--r-- | linux-core/i915_drv.c | 2 | 
5 files changed, 73 insertions, 17 deletions
diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c index e1340205..d712a70f 100644 --- a/linux-core/drm_bo_move.c +++ b/linux-core/drm_bo_move.c @@ -333,8 +333,10 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo,  	if (evict) {  		ret = drm_bo_wait(bo, 0, 1, 0); -		if (ret) +		if (ret) { +		  DRM_ERROR("Wait failure\n");  			return ret; +		}  		if (old_mem->mm_node) {  			mutex_lock(&dev->struct_mutex);  			drm_mm_put_block(old_mem->mm_node); diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index 5889ee4d..634a1782 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -217,6 +217,7 @@ void drm_mm_put_block(drm_mm_node_t * cur)  		drm_ctl_free(cur, sizeof(*cur), DRM_MEM_MM);  	}  } +EXPORT_SYMBOL(drm_mm_put_block);  drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,  				  unsigned long size, diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index fa55a8b4..8cd961d7 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -344,3 +344,4 @@ int drm_bind_ttm(drm_ttm_t * ttm, int cached, unsigned long aper_offset)  	return 0;  } +EXPORT_SYMBOL(drm_bind_ttm); diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 41f05b78..70ba9a67 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -132,37 +132,28 @@ static void i915_emit_copy_blit(drm_device_t *dev,  	if (!dev_priv)  		return; -	if (direction) { -		stride = -stride; -		src_offset += (pages - 1) << PAGE_SHIFT; -		dst_offset += (pages - 1) << PAGE_SHIFT; -	} - +	i915_kernel_lost_context(dev);  	while(pages > 0) {  		cur_pages = pages;  		if (cur_pages > 2048)  			cur_pages = 2048;  		pages -= cur_pages; -		BEGIN_LP_RING(8); -		OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | +		BEGIN_LP_RING(6); +		OUT_RING(SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |  			 XY_SRC_COPY_BLT_WRITE_RGB);  		OUT_RING((stride & 0xffff) | ( 0xcc << 16) | (1 << 24) |  -			 (1 << 25)); -		OUT_RING(0); -		OUT_RING((cur_pages << 16) | (PAGE_SIZE >> 2)); +			 (1 << 25) | (direction ? (1 << 30) : 0)); +		OUT_RING((cur_pages << 16) | PAGE_SIZE);  		OUT_RING(dst_offset); -		OUT_RING(0);  		OUT_RING(stride & 0xffff);  		OUT_RING(src_offset);  		ADVANCE_LP_RING(); -		dst_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1); -		src_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1);  	}  	return;  } -static int drm_bo_move_blit(drm_buffer_object_t *bo, +static int i915_move_blit(drm_buffer_object_t *bo,  			    int evict,  			    int no_wait,  			    drm_bo_mem_reg_t *new_mem) @@ -191,5 +182,66 @@ static int drm_bo_move_blit(drm_buffer_object_t *bo,  					 new_mem);  } +/* + * Flip destination ttm into cached-coherent AGP,  + * then blit and subsequently move out again. + */ + + +static int i915_move_flip(drm_buffer_object_t *bo, +			  int evict, +			  int no_wait, +			  drm_bo_mem_reg_t *new_mem) +{ +	drm_device_t *dev = bo->dev; +	drm_bo_mem_reg_t tmp_mem; +	int ret; + +	tmp_mem = *new_mem; +	tmp_mem.mm_node = NULL; +	tmp_mem.mask = DRM_BO_FLAG_MEM_TT | +	        DRM_BO_FLAG_CACHED  | +		DRM_BO_FLAG_FORCE_CACHING; +	 +	ret = drm_bo_mem_space(dev, &tmp_mem, no_wait); +	if (ret)  +		return ret; +	ret = drm_bind_ttm(bo->ttm, 1, tmp_mem.mm_node->start); +	if (ret)  +		goto out_cleanup; +	ret = i915_move_blit(bo, 1, no_wait, &tmp_mem); +	if (ret)  +		goto out_cleanup; +	 +	ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem); +out_cleanup: +	if (tmp_mem.mm_node) { +		mutex_lock(&dev->struct_mutex); +		drm_mm_put_block(tmp_mem.mm_node); +		tmp_mem.mm_node = NULL; +		mutex_unlock(&dev->struct_mutex); +	} +	return ret; +} + +	 +int i915_move(drm_buffer_object_t *bo, +	      int evict, +	      int no_wait, +	      drm_bo_mem_reg_t *new_mem) +{ +	drm_bo_mem_reg_t *old_mem = &bo->mem; + +	if (old_mem->mem_type == DRM_BO_MEM_LOCAL)  +		return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); +	if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { +		if (i915_move_flip(bo, evict, no_wait, new_mem))  +			return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); +	} else { +		if (i915_move_blit(bo, evict, no_wait, new_mem))  +			return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); +	} +	return 0; +} diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 19b63b7f..848ffa78 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -64,7 +64,7 @@ static drm_bo_driver_t i915_bo_driver = {  	.invalidate_caches = i915_invalidate_caches,  	.init_mem_type = i915_init_mem_type,  	.evict_flags = i915_evict_flags, -	.move = NULL, +	.move = i915_move,  };  #endif  | 
