mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 03:06:43 +00:00
Merge tag 'drm-intel-next-fixes-2019-05-15' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- Disable framebuffer compression on Geminilake - Fixes for HSW EDP fastset and a IRQ handler vs. RCU race Signed-off-by: Dave Airlie <airlied@redhat.com> From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190515074817.GA10472@jlahtine-desk.ger.corp.intel.com
This commit is contained in:
commit
dc28d5742b
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
|
EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
|
||||||
EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);
|
EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL(dma_fence_signaled);
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(dma_fence_stub_lock);
|
static DEFINE_SPINLOCK(dma_fence_stub_lock);
|
||||||
static struct dma_fence dma_fence_stub;
|
static struct dma_fence dma_fence_stub;
|
||||||
|
@ -452,6 +452,7 @@ void __i915_request_submit(struct i915_request *request)
|
|||||||
set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags);
|
set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags);
|
||||||
|
|
||||||
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) &&
|
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) &&
|
||||||
|
!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) &&
|
||||||
!i915_request_enable_breadcrumb(request))
|
!i915_request_enable_breadcrumb(request))
|
||||||
intel_engine_queue_breadcrumbs(engine);
|
intel_engine_queue_breadcrumbs(engine);
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
|
#include <trace/events/dma_fence.h>
|
||||||
#include <uapi/linux/sched/types.h>
|
#include <uapi/linux/sched/types.h>
|
||||||
|
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
@ -80,9 +81,39 @@ static inline bool __request_completed(const struct i915_request *rq)
|
|||||||
return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
|
return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
__dma_fence_signal(struct dma_fence *fence)
|
||||||
|
{
|
||||||
|
return !test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__dma_fence_signal__timestamp(struct dma_fence *fence, ktime_t timestamp)
|
||||||
|
{
|
||||||
|
fence->timestamp = timestamp;
|
||||||
|
set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
|
||||||
|
trace_dma_fence_signaled(fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__dma_fence_signal__notify(struct dma_fence *fence)
|
||||||
|
{
|
||||||
|
struct dma_fence_cb *cur, *tmp;
|
||||||
|
|
||||||
|
lockdep_assert_held(fence->lock);
|
||||||
|
lockdep_assert_irqs_disabled();
|
||||||
|
|
||||||
|
list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
|
||||||
|
INIT_LIST_HEAD(&cur->node);
|
||||||
|
cur->func(fence, cur);
|
||||||
|
}
|
||||||
|
INIT_LIST_HEAD(&fence->cb_list);
|
||||||
|
}
|
||||||
|
|
||||||
void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct intel_breadcrumbs *b = &engine->breadcrumbs;
|
struct intel_breadcrumbs *b = &engine->breadcrumbs;
|
||||||
|
const ktime_t timestamp = ktime_get();
|
||||||
struct intel_context *ce, *cn;
|
struct intel_context *ce, *cn;
|
||||||
struct list_head *pos, *next;
|
struct list_head *pos, *next;
|
||||||
LIST_HEAD(signal);
|
LIST_HEAD(signal);
|
||||||
@ -104,6 +135,10 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
|||||||
|
|
||||||
GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
|
GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
|
||||||
&rq->fence.flags));
|
&rq->fence.flags));
|
||||||
|
clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
|
||||||
|
|
||||||
|
if (!__dma_fence_signal(&rq->fence))
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Queue for execution after dropping the signaling
|
* Queue for execution after dropping the signaling
|
||||||
@ -111,14 +146,6 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
|||||||
* more signalers to the same context or engine.
|
* more signalers to the same context or engine.
|
||||||
*/
|
*/
|
||||||
i915_request_get(rq);
|
i915_request_get(rq);
|
||||||
|
|
||||||
/*
|
|
||||||
* We may race with direct invocation of
|
|
||||||
* dma_fence_signal(), e.g. i915_request_retire(),
|
|
||||||
* so we need to acquire our reference to the request
|
|
||||||
* before we cancel the breadcrumb.
|
|
||||||
*/
|
|
||||||
clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
|
|
||||||
list_add_tail(&rq->signal_link, &signal);
|
list_add_tail(&rq->signal_link, &signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +168,12 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
|||||||
struct i915_request *rq =
|
struct i915_request *rq =
|
||||||
list_entry(pos, typeof(*rq), signal_link);
|
list_entry(pos, typeof(*rq), signal_link);
|
||||||
|
|
||||||
dma_fence_signal(&rq->fence);
|
__dma_fence_signal__timestamp(&rq->fence, timestamp);
|
||||||
|
|
||||||
|
spin_lock(&rq->lock);
|
||||||
|
__dma_fence_signal__notify(&rq->fence);
|
||||||
|
spin_unlock(&rq->lock);
|
||||||
|
|
||||||
i915_request_put(rq);
|
i915_request_put(rq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,19 +275,17 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
|
|||||||
|
|
||||||
bool i915_request_enable_breadcrumb(struct i915_request *rq)
|
bool i915_request_enable_breadcrumb(struct i915_request *rq)
|
||||||
{
|
{
|
||||||
struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
|
lockdep_assert_held(&rq->lock);
|
||||||
|
lockdep_assert_irqs_disabled();
|
||||||
|
|
||||||
GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
|
if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) {
|
||||||
|
struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
|
||||||
if (!test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
spin_lock(&b->irq_lock);
|
|
||||||
if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags) &&
|
|
||||||
!__request_completed(rq)) {
|
|
||||||
struct intel_context *ce = rq->hw_context;
|
struct intel_context *ce = rq->hw_context;
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
|
|
||||||
|
spin_lock(&b->irq_lock);
|
||||||
|
GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
|
||||||
|
|
||||||
__intel_breadcrumbs_arm_irq(b);
|
__intel_breadcrumbs_arm_irq(b);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -284,8 +314,8 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
|
|||||||
list_move_tail(&ce->signal_link, &b->signalers);
|
list_move_tail(&ce->signal_link, &b->signalers);
|
||||||
|
|
||||||
set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
|
set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
|
||||||
|
spin_unlock(&b->irq_lock);
|
||||||
}
|
}
|
||||||
spin_unlock(&b->irq_lock);
|
|
||||||
|
|
||||||
return !__request_completed(rq);
|
return !__request_completed(rq);
|
||||||
}
|
}
|
||||||
@ -294,9 +324,15 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq)
|
|||||||
{
|
{
|
||||||
struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
|
struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
|
||||||
|
|
||||||
if (!test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags))
|
lockdep_assert_held(&rq->lock);
|
||||||
return;
|
lockdep_assert_irqs_disabled();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We must wait for b->irq_lock so that we know the interrupt handler
|
||||||
|
* has released its reference to the intel_context and has completed
|
||||||
|
* the DMA_FENCE_FLAG_SIGNALED_BIT/I915_FENCE_FLAG_SIGNAL dance (if
|
||||||
|
* required).
|
||||||
|
*/
|
||||||
spin_lock(&b->irq_lock);
|
spin_lock(&b->irq_lock);
|
||||||
if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) {
|
if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) {
|
||||||
struct intel_context *ce = rq->hw_context;
|
struct intel_context *ce = rq->hw_context;
|
||||||
|
@ -12082,6 +12082,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
|
|||||||
struct intel_crtc_state *pipe_config,
|
struct intel_crtc_state *pipe_config,
|
||||||
bool adjust)
|
bool adjust)
|
||||||
{
|
{
|
||||||
|
struct intel_crtc *crtc = to_intel_crtc(current_config->base.crtc);
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
bool fixup_inherited = adjust &&
|
bool fixup_inherited = adjust &&
|
||||||
(current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
|
(current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
|
||||||
@ -12303,6 +12304,14 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
|
|||||||
PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
|
PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
|
||||||
PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
|
PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Changing the EDP transcoder input mux
|
||||||
|
* (A_ONOFF vs. A_ON) requires a full modeset.
|
||||||
|
*/
|
||||||
|
if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A &&
|
||||||
|
current_config->cpu_transcoder == TRANSCODER_EDP)
|
||||||
|
PIPE_CONF_CHECK_BOOL(pch_pfit.enabled);
|
||||||
|
|
||||||
if (!adjust) {
|
if (!adjust) {
|
||||||
PIPE_CONF_CHECK_I(pipe_src_w);
|
PIPE_CONF_CHECK_I(pipe_src_w);
|
||||||
PIPE_CONF_CHECK_I(pipe_src_h);
|
PIPE_CONF_CHECK_I(pipe_src_h);
|
||||||
|
@ -1280,6 +1280,10 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
|
|||||||
if (!HAS_FBC(dev_priv))
|
if (!HAS_FBC(dev_priv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */
|
||||||
|
if (IS_GEMINILAKE(dev_priv))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
|
if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/circ_buf.h>
|
#include <linux/circ_buf.h>
|
||||||
#include <trace/events/dma_fence.h>
|
|
||||||
|
|
||||||
#include "intel_guc_submission.h"
|
#include "intel_guc_submission.h"
|
||||||
#include "intel_lrc_reg.h"
|
#include "intel_lrc_reg.h"
|
||||||
|
@ -311,10 +311,17 @@ retry:
|
|||||||
pipe_config->base.mode_changed = pipe_config->has_psr;
|
pipe_config->base.mode_changed = pipe_config->has_psr;
|
||||||
pipe_config->crc_enabled = enable;
|
pipe_config->crc_enabled = enable;
|
||||||
|
|
||||||
if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A) {
|
if (IS_HASWELL(dev_priv) &&
|
||||||
|
pipe_config->base.active && crtc->pipe == PIPE_A &&
|
||||||
|
pipe_config->cpu_transcoder == TRANSCODER_EDP) {
|
||||||
|
bool old_need_power_well = pipe_config->pch_pfit.enabled ||
|
||||||
|
pipe_config->pch_pfit.force_thru;
|
||||||
|
bool new_need_power_well = pipe_config->pch_pfit.enabled ||
|
||||||
|
enable;
|
||||||
|
|
||||||
pipe_config->pch_pfit.force_thru = enable;
|
pipe_config->pch_pfit.force_thru = enable;
|
||||||
if (pipe_config->cpu_transcoder == TRANSCODER_EDP &&
|
|
||||||
pipe_config->pch_pfit.enabled != enable)
|
if (old_need_power_well != new_need_power_well)
|
||||||
pipe_config->base.connectors_changed = true;
|
pipe_config->base.connectors_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user