diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 2 |
5 files changed, 43 insertions, 29 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 24b7796c33af..b97d62d81905 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1013,7 +1013,8 @@ void i915_gem_process_flushing_list(struct drm_device *dev, | |||
1013 | struct intel_ring_buffer *ring); | 1013 | struct intel_ring_buffer *ring); |
1014 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 1014 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
1015 | int write); | 1015 | int write); |
1016 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | 1016 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, |
1017 | bool pipelined); | ||
1017 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1018 | int i915_gem_attach_phys_object(struct drm_device *dev, |
1018 | struct drm_gem_object *obj, | 1019 | struct drm_gem_object *obj, |
1019 | int id, | 1020 | int id, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4a0d85c78d47..85a3cf4ab481 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2597,6 +2597,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, | |||
2597 | /* Queue the GPU write cache flushing we need. */ | 2597 | /* Queue the GPU write cache flushing we need. */ |
2598 | old_write_domain = obj->write_domain; | 2598 | old_write_domain = obj->write_domain; |
2599 | i915_gem_flush(dev, 0, obj->write_domain); | 2599 | i915_gem_flush(dev, 0, obj->write_domain); |
2600 | BUG_ON(obj->write_domain); | ||
2600 | 2601 | ||
2601 | trace_i915_gem_object_change_domain(obj, | 2602 | trace_i915_gem_object_change_domain(obj, |
2602 | obj->read_domains, | 2603 | obj->read_domains, |
@@ -2704,7 +2705,8 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | |||
2704 | * wait, as in modesetting process we're not supposed to be interrupted. | 2705 | * wait, as in modesetting process we're not supposed to be interrupted. |
2705 | */ | 2706 | */ |
2706 | int | 2707 | int |
2707 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | 2708 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, |
2709 | bool pipelined) | ||
2708 | { | 2710 | { |
2709 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2711 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2710 | uint32_t old_read_domains; | 2712 | uint32_t old_read_domains; |
@@ -2714,8 +2716,8 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | |||
2714 | if (obj_priv->gtt_space == NULL) | 2716 | if (obj_priv->gtt_space == NULL) |
2715 | return -EINVAL; | 2717 | return -EINVAL; |
2716 | 2718 | ||
2717 | ret = i915_gem_object_flush_gpu_write_domain(obj, true); | 2719 | ret = i915_gem_object_flush_gpu_write_domain(obj, pipelined); |
2718 | if (ret != 0) | 2720 | if (ret) |
2719 | return ret; | 2721 | return ret; |
2720 | 2722 | ||
2721 | i915_gem_object_flush_cpu_write_domain(obj); | 2723 | i915_gem_object_flush_cpu_write_domain(obj); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 810ed2dca4c7..a7628fdd0c4c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1417,7 +1417,9 @@ out_disable: | |||
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | int | 1419 | int |
1420 | intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | 1420 | intel_pin_and_fence_fb_obj(struct drm_device *dev, |
1421 | struct drm_gem_object *obj, | ||
1422 | bool pipelined) | ||
1421 | { | 1423 | { |
1422 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1424 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1423 | u32 alignment; | 1425 | u32 alignment; |
@@ -1445,14 +1447,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | |||
1445 | } | 1447 | } |
1446 | 1448 | ||
1447 | ret = i915_gem_object_pin(obj, alignment); | 1449 | ret = i915_gem_object_pin(obj, alignment); |
1448 | if (ret != 0) | 1450 | if (ret) |
1449 | return ret; | 1451 | return ret; |
1450 | 1452 | ||
1451 | ret = i915_gem_object_set_to_display_plane(obj); | 1453 | ret = i915_gem_object_set_to_display_plane(obj, pipelined); |
1452 | if (ret != 0) { | 1454 | if (ret) |
1453 | i915_gem_object_unpin(obj); | 1455 | goto err_unpin; |
1454 | return ret; | ||
1455 | } | ||
1456 | 1456 | ||
1457 | /* Install a fence for tiled scan-out. Pre-i965 always needs a | 1457 | /* Install a fence for tiled scan-out. Pre-i965 always needs a |
1458 | * fence, whereas 965+ only requires a fence if using | 1458 | * fence, whereas 965+ only requires a fence if using |
@@ -1462,13 +1462,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | |||
1462 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1462 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && |
1463 | obj_priv->tiling_mode != I915_TILING_NONE) { | 1463 | obj_priv->tiling_mode != I915_TILING_NONE) { |
1464 | ret = i915_gem_object_get_fence_reg(obj); | 1464 | ret = i915_gem_object_get_fence_reg(obj); |
1465 | if (ret != 0) { | 1465 | if (ret) |
1466 | i915_gem_object_unpin(obj); | 1466 | goto err_unpin; |
1467 | return ret; | ||
1468 | } | ||
1469 | } | 1467 | } |
1470 | 1468 | ||
1471 | return 0; | 1469 | return 0; |
1470 | |||
1471 | err_unpin: | ||
1472 | i915_gem_object_unpin(obj); | ||
1473 | return ret; | ||
1472 | } | 1474 | } |
1473 | 1475 | ||
1474 | /* Assume fb object is pinned & idle & fenced and just update base pointers */ | 1476 | /* Assume fb object is pinned & idle & fenced and just update base pointers */ |
@@ -1589,7 +1591,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1589 | obj_priv = to_intel_bo(obj); | 1591 | obj_priv = to_intel_bo(obj); |
1590 | 1592 | ||
1591 | mutex_lock(&dev->struct_mutex); | 1593 | mutex_lock(&dev->struct_mutex); |
1592 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 1594 | ret = intel_pin_and_fence_fb_obj(dev, obj, false); |
1593 | if (ret != 0) { | 1595 | if (ret != 0) { |
1594 | mutex_unlock(&dev->struct_mutex); | 1596 | mutex_unlock(&dev->struct_mutex); |
1595 | return ret; | 1597 | return ret; |
@@ -5004,7 +5006,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5004 | struct intel_unpin_work *work; | 5006 | struct intel_unpin_work *work; |
5005 | unsigned long flags, offset; | 5007 | unsigned long flags, offset; |
5006 | int pipe = intel_crtc->pipe; | 5008 | int pipe = intel_crtc->pipe; |
5007 | u32 pf, pipesrc; | 5009 | u32 was_dirty, pf, pipesrc; |
5008 | int ret; | 5010 | int ret; |
5009 | 5011 | ||
5010 | work = kzalloc(sizeof *work, GFP_KERNEL); | 5012 | work = kzalloc(sizeof *work, GFP_KERNEL); |
@@ -5033,7 +5035,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5033 | obj = intel_fb->obj; | 5035 | obj = intel_fb->obj; |
5034 | 5036 | ||
5035 | mutex_lock(&dev->struct_mutex); | 5037 | mutex_lock(&dev->struct_mutex); |
5036 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 5038 | was_dirty = obj->write_domain & I915_GEM_GPU_DOMAINS; |
5039 | ret = intel_pin_and_fence_fb_obj(dev, obj, true); | ||
5037 | if (ret) | 5040 | if (ret) |
5038 | goto cleanup_work; | 5041 | goto cleanup_work; |
5039 | 5042 | ||
@@ -5051,17 +5054,24 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5051 | atomic_inc(&obj_priv->pending_flip); | 5054 | atomic_inc(&obj_priv->pending_flip); |
5052 | work->pending_flip_obj = obj; | 5055 | work->pending_flip_obj = obj; |
5053 | 5056 | ||
5054 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | 5057 | if (was_dirty || IS_GEN3(dev) || IS_GEN2(dev)) { |
5055 | u32 flip_mask; | 5058 | BEGIN_LP_RING(2); |
5059 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | ||
5060 | u32 flip_mask; | ||
5056 | 5061 | ||
5057 | if (intel_crtc->plane) | 5062 | /* Can't queue multiple flips, so wait for the previous |
5058 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | 5063 | * one to finish before executing the next. |
5059 | else | 5064 | */ |
5060 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
5061 | 5065 | ||
5062 | BEGIN_LP_RING(2); | 5066 | if (intel_crtc->plane) |
5063 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | 5067 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
5064 | OUT_RING(0); | 5068 | else |
5069 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
5070 | |||
5071 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
5072 | } else | ||
5073 | OUT_RING(MI_NOOP); | ||
5074 | OUT_RING(MI_FLUSH); | ||
5065 | ADVANCE_LP_RING(); | 5075 | ADVANCE_LP_RING(); |
5066 | } | 5076 | } |
5067 | 5077 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5171b0523178..31f072d31e37 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -281,7 +281,8 @@ extern void ironlake_enable_drps(struct drm_device *dev); | |||
281 | extern void ironlake_disable_drps(struct drm_device *dev); | 281 | extern void ironlake_disable_drps(struct drm_device *dev); |
282 | 282 | ||
283 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 283 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
284 | struct drm_gem_object *obj); | 284 | struct drm_gem_object *obj, |
285 | bool pipelined); | ||
285 | 286 | ||
286 | extern int intel_framebuffer_init(struct drm_device *dev, | 287 | extern int intel_framebuffer_init(struct drm_device *dev, |
287 | struct intel_framebuffer *ifb, | 288 | struct intel_framebuffer *ifb, |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index e2d13e394a0d..8a23bf772c95 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -94,7 +94,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
94 | mutex_lock(&dev->struct_mutex); | 94 | mutex_lock(&dev->struct_mutex); |
95 | 95 | ||
96 | /* Flush everything out, we'll be doing GTT only from now on */ | 96 | /* Flush everything out, we'll be doing GTT only from now on */ |
97 | ret = intel_pin_and_fence_fb_obj(dev, fbo); | 97 | ret = intel_pin_and_fence_fb_obj(dev, fbo, false); |
98 | if (ret) { | 98 | if (ret) { |
99 | DRM_ERROR("failed to pin fb: %d\n", ret); | 99 | DRM_ERROR("failed to pin fb: %d\n", ret); |
100 | goto out_unref; | 100 | goto out_unref; |