aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma-buf/dma-fence.c1
-rw-r--r--drivers/gpu/drm/i915/i915_request.c1
-rw-r--r--drivers/gpu/drm/i915/intel_breadcrumbs.c78
-rw-r--r--drivers/gpu/drm/i915/intel_display.c9
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c4
-rw-r--r--drivers/gpu/drm/i915/intel_guc_submission.c1
-rw-r--r--drivers/gpu/drm/i915/intel_pipe_crc.c13
7 files changed, 82 insertions, 25 deletions
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 3aa8733f832a..9bf06042619a 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -29,6 +29,7 @@
29 29
30EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit); 30EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
31EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal); 31EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);
32EXPORT_TRACEPOINT_SYMBOL(dma_fence_signaled);
32 33
33static DEFINE_SPINLOCK(dma_fence_stub_lock); 34static DEFINE_SPINLOCK(dma_fence_stub_lock);
34static struct dma_fence dma_fence_stub; 35static struct dma_fence dma_fence_stub;
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index ce342f7f7ddb..f6c78c0fa74b 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -452,6 +452,7 @@ void __i915_request_submit(struct i915_request *request)
452 set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags); 452 set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags);
453 453
454 if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) && 454 if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) &&
455 !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) &&
455 !i915_request_enable_breadcrumb(request)) 456 !i915_request_enable_breadcrumb(request))
456 intel_engine_queue_breadcrumbs(engine); 457 intel_engine_queue_breadcrumbs(engine);
457 458
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 3cbffd400b1b..832cb6b1e9bd 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/kthread.h> 25#include <linux/kthread.h>
26#include <trace/events/dma_fence.h>
26#include <uapi/linux/sched/types.h> 27#include <uapi/linux/sched/types.h>
27 28
28#include "i915_drv.h" 29#include "i915_drv.h"
@@ -80,9 +81,39 @@ static inline bool __request_completed(const struct i915_request *rq)
80 return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); 81 return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
81} 82}
82 83
84static bool
85__dma_fence_signal(struct dma_fence *fence)
86{
87 return !test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags);
88}
89
90static void
91__dma_fence_signal__timestamp(struct dma_fence *fence, ktime_t timestamp)
92{
93 fence->timestamp = timestamp;
94 set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
95 trace_dma_fence_signaled(fence);
96}
97
98static void
99__dma_fence_signal__notify(struct dma_fence *fence)
100{
101 struct dma_fence_cb *cur, *tmp;
102
103 lockdep_assert_held(fence->lock);
104 lockdep_assert_irqs_disabled();
105
106 list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
107 INIT_LIST_HEAD(&cur->node);
108 cur->func(fence, cur);
109 }
110 INIT_LIST_HEAD(&fence->cb_list);
111}
112
83void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) 113void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
84{ 114{
85 struct intel_breadcrumbs *b = &engine->breadcrumbs; 115 struct intel_breadcrumbs *b = &engine->breadcrumbs;
116 const ktime_t timestamp = ktime_get();
86 struct intel_context *ce, *cn; 117 struct intel_context *ce, *cn;
87 struct list_head *pos, *next; 118 struct list_head *pos, *next;
88 LIST_HEAD(signal); 119 LIST_HEAD(signal);
@@ -104,6 +135,10 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
104 135
105 GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL, 136 GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
106 &rq->fence.flags)); 137 &rq->fence.flags));
138 clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
139
140 if (!__dma_fence_signal(&rq->fence))
141 continue;
107 142
108 /* 143 /*
109 * Queue for execution after dropping the signaling 144 * Queue for execution after dropping the signaling
@@ -111,14 +146,6 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
111 * more signalers to the same context or engine. 146 * more signalers to the same context or engine.
112 */ 147 */
113 i915_request_get(rq); 148 i915_request_get(rq);
114
115 /*
116 * We may race with direct invocation of
117 * dma_fence_signal(), e.g. i915_request_retire(),
118 * so we need to acquire our reference to the request
119 * before we cancel the breadcrumb.
120 */
121 clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
122 list_add_tail(&rq->signal_link, &signal); 149 list_add_tail(&rq->signal_link, &signal);
123 } 150 }
124 151
@@ -141,7 +168,12 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
141 struct i915_request *rq = 168 struct i915_request *rq =
142 list_entry(pos, typeof(*rq), signal_link); 169 list_entry(pos, typeof(*rq), signal_link);
143 170
144 dma_fence_signal(&rq->fence); 171 __dma_fence_signal__timestamp(&rq->fence, timestamp);
172
173 spin_lock(&rq->lock);
174 __dma_fence_signal__notify(&rq->fence);
175 spin_unlock(&rq->lock);
176
145 i915_request_put(rq); 177 i915_request_put(rq);
146 } 178 }
147} 179}
@@ -243,19 +275,17 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
243 275
244bool i915_request_enable_breadcrumb(struct i915_request *rq) 276bool i915_request_enable_breadcrumb(struct i915_request *rq)
245{ 277{
246 struct intel_breadcrumbs *b = &rq->engine->breadcrumbs; 278 lockdep_assert_held(&rq->lock);
247 279 lockdep_assert_irqs_disabled();
248 GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
249 280
250 if (!test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) 281 if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) {
251 return true; 282 struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
252
253 spin_lock(&b->irq_lock);
254 if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags) &&
255 !__request_completed(rq)) {
256 struct intel_context *ce = rq->hw_context; 283 struct intel_context *ce = rq->hw_context;
257 struct list_head *pos; 284 struct list_head *pos;
258 285
286 spin_lock(&b->irq_lock);
287 GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
288
259 __intel_breadcrumbs_arm_irq(b); 289 __intel_breadcrumbs_arm_irq(b);
260 290
261 /* 291 /*
@@ -284,8 +314,8 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
284 list_move_tail(&ce->signal_link, &b->signalers); 314 list_move_tail(&ce->signal_link, &b->signalers);
285 315
286 set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); 316 set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
317 spin_unlock(&b->irq_lock);
287 } 318 }
288 spin_unlock(&b->irq_lock);
289 319
290 return !__request_completed(rq); 320 return !__request_completed(rq);
291} 321}
@@ -294,9 +324,15 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq)
294{ 324{
295 struct intel_breadcrumbs *b = &rq->engine->breadcrumbs; 325 struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
296 326
297 if (!test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) 327 lockdep_assert_held(&rq->lock);
298 return; 328 lockdep_assert_irqs_disabled();
299 329
330 /*
331 * We must wait for b->irq_lock so that we know the interrupt handler
332 * has released its reference to the intel_context and has completed
333 * the DMA_FENCE_FLAG_SIGNALED_BIT/I915_FENCE_FLAG_SIGNAL dance (if
334 * required).
335 */
300 spin_lock(&b->irq_lock); 336 spin_lock(&b->irq_lock);
301 if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) { 337 if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) {
302 struct intel_context *ce = rq->hw_context; 338 struct intel_context *ce = rq->hw_context;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3bd40a4a6739..5098228f1302 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12082,6 +12082,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
12082 struct intel_crtc_state *pipe_config, 12082 struct intel_crtc_state *pipe_config,
12083 bool adjust) 12083 bool adjust)
12084{ 12084{
12085 struct intel_crtc *crtc = to_intel_crtc(current_config->base.crtc);
12085 bool ret = true; 12086 bool ret = true;
12086 bool fixup_inherited = adjust && 12087 bool fixup_inherited = adjust &&
12087 (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) && 12088 (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
@@ -12303,6 +12304,14 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
12303 PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios); 12304 PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
12304 PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits); 12305 PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
12305 12306
12307 /*
12308 * Changing the EDP transcoder input mux
12309 * (A_ONOFF vs. A_ON) requires a full modeset.
12310 */
12311 if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A &&
12312 current_config->cpu_transcoder == TRANSCODER_EDP)
12313 PIPE_CONF_CHECK_BOOL(pch_pfit.enabled);
12314
12306 if (!adjust) { 12315 if (!adjust) {
12307 PIPE_CONF_CHECK_I(pipe_src_w); 12316 PIPE_CONF_CHECK_I(pipe_src_w);
12308 PIPE_CONF_CHECK_I(pipe_src_h); 12317 PIPE_CONF_CHECK_I(pipe_src_h);
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index c805a0966395..5679f2fffb7c 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -1280,6 +1280,10 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
1280 if (!HAS_FBC(dev_priv)) 1280 if (!HAS_FBC(dev_priv))
1281 return 0; 1281 return 0;
1282 1282
1283 /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */
1284 if (IS_GEMINILAKE(dev_priv))
1285 return 0;
1286
1283 if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) 1287 if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
1284 return 1; 1288 return 1;
1285 1289
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index 37f60cb8e9e1..46cd0e70aecb 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -23,7 +23,6 @@
23 */ 23 */
24 24
25#include <linux/circ_buf.h> 25#include <linux/circ_buf.h>
26#include <trace/events/dma_fence.h>
27 26
28#include "intel_guc_submission.h" 27#include "intel_guc_submission.h"
29#include "intel_lrc_reg.h" 28#include "intel_lrc_reg.h"
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index e94b5b1bc1b7..e7c7be4911c1 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -311,10 +311,17 @@ retry:
311 pipe_config->base.mode_changed = pipe_config->has_psr; 311 pipe_config->base.mode_changed = pipe_config->has_psr;
312 pipe_config->crc_enabled = enable; 312 pipe_config->crc_enabled = enable;
313 313
314 if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A) { 314 if (IS_HASWELL(dev_priv) &&
315 pipe_config->base.active && crtc->pipe == PIPE_A &&
316 pipe_config->cpu_transcoder == TRANSCODER_EDP) {
317 bool old_need_power_well = pipe_config->pch_pfit.enabled ||
318 pipe_config->pch_pfit.force_thru;
319 bool new_need_power_well = pipe_config->pch_pfit.enabled ||
320 enable;
321
315 pipe_config->pch_pfit.force_thru = enable; 322 pipe_config->pch_pfit.force_thru = enable;
316 if (pipe_config->cpu_transcoder == TRANSCODER_EDP && 323
317 pipe_config->pch_pfit.enabled != enable) 324 if (old_need_power_well != new_need_power_well)
318 pipe_config->base.connectors_changed = true; 325 pipe_config->base.connectors_changed = true;
319 } 326 }
320 327