Skip to content

Commit

Permalink
Merge tag 'drm-intel-fixes-2020-03-05' of git://anongit.freedesktop.o…
Browse files Browse the repository at this point in the history
…rg/drm/drm-intel into drm-fixes

drm/i915 fixes for v5.6-rc5:
- Break up long lists of object reclaim with cond_resched()
- PSR probe fix
- TGL workarounds
- Selftest return value fix
- Drop timeline mutex while waiting for retirement
- Wait for OA configuration completion before writes to OA buffer

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87eeu7nl6z.fsf@intel.com
  • Loading branch information
Dave Airlie committed Mar 6, 2020
2 parents 26398db + 169c0aa commit 64c3fd5
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 57 deletions.
29 changes: 24 additions & 5 deletions drivers/gpu/drm/i915/display/intel_display_power.c
Original file line number Diff line number Diff line change
Expand Up @@ -4466,13 +4466,19 @@ static void icl_dbuf_disable(struct drm_i915_private *dev_priv)

static void icl_mbus_init(struct drm_i915_private *dev_priv)
{
u32 val;
u32 mask, val;

val = MBUS_ABOX_BT_CREDIT_POOL1(16) |
MBUS_ABOX_BT_CREDIT_POOL2(16) |
MBUS_ABOX_B_CREDIT(1) |
MBUS_ABOX_BW_CREDIT(1);
mask = MBUS_ABOX_BT_CREDIT_POOL1_MASK |
MBUS_ABOX_BT_CREDIT_POOL2_MASK |
MBUS_ABOX_B_CREDIT_MASK |
MBUS_ABOX_BW_CREDIT_MASK;

val = I915_READ(MBUS_ABOX_CTL);
val &= ~mask;
val |= MBUS_ABOX_BT_CREDIT_POOL1(16) |
MBUS_ABOX_BT_CREDIT_POOL2(16) |
MBUS_ABOX_B_CREDIT(1) |
MBUS_ABOX_BW_CREDIT(1);
I915_WRITE(MBUS_ABOX_CTL, val);
}

Expand Down Expand Up @@ -4968,8 +4974,21 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
I915_WRITE(BW_BUDDY1_CTL, BW_BUDDY_DISABLE);
I915_WRITE(BW_BUDDY2_CTL, BW_BUDDY_DISABLE);
} else {
u32 val;

I915_WRITE(BW_BUDDY1_PAGE_MASK, table[i].page_mask);
I915_WRITE(BW_BUDDY2_PAGE_MASK, table[i].page_mask);

/* Wa_22010178259:tgl */
val = I915_READ(BW_BUDDY1_CTL);
val &= ~BW_BUDDY_TLB_REQ_TIMER_MASK;
val |= REG_FIELD_PREP(BW_BUDDY_TLB_REQ_TIMER_MASK, 0x8);
I915_WRITE(BW_BUDDY1_CTL, val);

val = I915_READ(BW_BUDDY2_CTL);
val &= ~BW_BUDDY_TLB_REQ_TIMER_MASK;
val |= REG_FIELD_PREP(BW_BUDDY_TLB_REQ_TIMER_MASK, 0x8);
I915_WRITE(BW_BUDDY2_CTL, val);
}
}

Expand Down
25 changes: 21 additions & 4 deletions drivers/gpu/drm/i915/display/intel_psr.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,10 +852,12 @@ void intel_psr_enable(struct intel_dp *intel_dp,
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);

if (!crtc_state->has_psr)
if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp)
return;

if (WARN_ON(!CAN_PSR(dev_priv)))
dev_priv->psr.force_mode_changed = false;

if (!crtc_state->has_psr)
return;

WARN_ON(dev_priv->drrs.dp);
Expand Down Expand Up @@ -1009,6 +1011,8 @@ void intel_psr_update(struct intel_dp *intel_dp,
if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp)
return;

dev_priv->psr.force_mode_changed = false;

mutex_lock(&dev_priv->psr.lock);

enable = crtc_state->has_psr && psr_global_enabled(psr->debug);
Expand Down Expand Up @@ -1534,7 +1538,7 @@ void intel_psr_atomic_check(struct drm_connector *connector,
struct drm_crtc_state *crtc_state;

if (!CAN_PSR(dev_priv) || !new_state->crtc ||
dev_priv->psr.initially_probed)
!dev_priv->psr.force_mode_changed)
return;

intel_connector = to_intel_connector(connector);
Expand All @@ -1545,5 +1549,18 @@ void intel_psr_atomic_check(struct drm_connector *connector,
crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
new_state->crtc);
crtc_state->mode_changed = true;
dev_priv->psr.initially_probed = true;
}

void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv;

if (!intel_dp)
return;

dev_priv = dp_to_i915(intel_dp);
if (!CAN_PSR(dev_priv) || intel_dp != dev_priv->psr.dp)
return;

dev_priv->psr.force_mode_changed = true;
}
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_psr.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ bool intel_psr_enabled(struct intel_dp *intel_dp);
void intel_psr_atomic_check(struct drm_connector *connector,
struct drm_connector_state *old_state,
struct drm_connector_state *new_state);
void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp);

#endif /* __INTEL_PSR_H__ */
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/gem/i915_gem_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,

/* But keep the pointer alive for RCU-protected lookups */
call_rcu(&obj->rcu, __i915_gem_free_object_rcu);
cond_resched();
}
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ static bool assert_mmap_offset(struct drm_i915_private *i915,

obj = i915_gem_object_create_internal(i915, size);
if (IS_ERR(obj))
return PTR_ERR(obj);
return false;

mmo = mmap_offset_attach(obj, I915_MMAP_OFFSET_GTT, NULL);
i915_gem_object_put(obj);
Expand Down
14 changes: 11 additions & 3 deletions drivers/gpu/drm/i915/gt/intel_gt_requests.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,24 +147,32 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)

fence = i915_active_fence_get(&tl->last_request);
if (fence) {
mutex_unlock(&tl->mutex);

timeout = dma_fence_wait_timeout(fence,
interruptible,
timeout);
dma_fence_put(fence);

/* Retirement is best effort */
if (!mutex_trylock(&tl->mutex)) {
active_count++;
goto out_active;
}
}
}

if (!retire_requests(tl) || flush_submission(gt))
active_count++;
mutex_unlock(&tl->mutex);

spin_lock(&timelines->lock);
out_active: spin_lock(&timelines->lock);

/* Resume iteration after dropping lock */
/* Resume list iteration after reacquiring spinlock */
list_safe_reset_next(tl, tn, link);
if (atomic_dec_and_test(&tl->active_count))
list_del(&tl->link);

mutex_unlock(&tl->mutex);

/* Defer the final release to after the spinlock */
if (refcount_dec_and_test(&tl->kref.refcount)) {
Expand Down
19 changes: 7 additions & 12 deletions drivers/gpu/drm/i915/gt/intel_workarounds.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,24 +575,19 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine,
static void tgl_ctx_workarounds_init(struct intel_engine_cs *engine,
struct i915_wa_list *wal)
{
u32 val;

/* Wa_1409142259:tgl */
WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3,
GEN12_DISABLE_CPS_AWARE_COLOR_PIPE);

/* Wa_1604555607:tgl */
val = intel_uncore_read(engine->uncore, FF_MODE2);
val &= ~FF_MODE2_TDS_TIMER_MASK;
val |= FF_MODE2_TDS_TIMER_128;
/*
* FIXME: FF_MODE2 register is not readable till TGL B0. We can
* enable verification of WA from the later steppings, which enables
* the read of FF_MODE2.
* Wa_1604555607:gen12 and Wa_1608008084:gen12
* FF_MODE2 register will return the wrong value when read. The default
* value for this register is zero for all fields and there are no bit
* masks. So instead of doing a RMW we should just write the TDS timer
* value for Wa_1604555607.
*/
wa_add(wal, FF_MODE2, FF_MODE2_TDS_TIMER_MASK, val,
IS_TGL_REVID(engine->i915, TGL_REVID_A0, TGL_REVID_A0) ? 0 :
FF_MODE2_TDS_TIMER_MASK);
wa_add(wal, FF_MODE2, FF_MODE2_TDS_TIMER_MASK,
FF_MODE2_TDS_TIMER_128, 0);
}

static void
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "display/intel_hotplug.h"
#include "display/intel_overlay.h"
#include "display/intel_pipe_crc.h"
#include "display/intel_psr.h"
#include "display/intel_sprite.h"
#include "display/intel_vga.h"

Expand Down Expand Up @@ -330,6 +331,8 @@ static int i915_driver_modeset_probe(struct drm_i915_private *i915)

intel_init_ipc(i915);

intel_psr_set_force_mode_changed(i915->psr.dp);

return 0;

cleanup_gem:
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ struct i915_psr {
bool dc3co_enabled;
u32 dc3co_exit_delay;
struct delayed_work idle_work;
bool initially_probed;
bool force_mode_changed;
};

#define QUIRK_LVDS_SSC_DISABLE (1<<1)
Expand Down
58 changes: 41 additions & 17 deletions drivers/gpu/drm/i915/i915_perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,17 +1954,18 @@ get_oa_vma(struct i915_perf_stream *stream, struct i915_oa_config *oa_config)
return i915_vma_get(oa_bo->vma);
}

static int emit_oa_config(struct i915_perf_stream *stream,
struct i915_oa_config *oa_config,
struct intel_context *ce)
static struct i915_request *
emit_oa_config(struct i915_perf_stream *stream,
struct i915_oa_config *oa_config,
struct intel_context *ce)
{
struct i915_request *rq;
struct i915_vma *vma;
int err;

vma = get_oa_vma(stream, oa_config);
if (IS_ERR(vma))
return PTR_ERR(vma);
return ERR_CAST(vma);

err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
if (err)
Expand All @@ -1989,21 +1990,26 @@ static int emit_oa_config(struct i915_perf_stream *stream,
err = rq->engine->emit_bb_start(rq,
vma->node.start, 0,
I915_DISPATCH_SECURE);
if (err)
goto err_add_request;

i915_request_get(rq);
err_add_request:
i915_request_add(rq);
err_vma_unpin:
i915_vma_unpin(vma);
err_vma_put:
i915_vma_put(vma);
return err;
return err ? ERR_PTR(err) : rq;
}

static struct intel_context *oa_context(struct i915_perf_stream *stream)
{
return stream->pinned_ctx ?: stream->engine->kernel_context;
}

static int hsw_enable_metric_set(struct i915_perf_stream *stream)
static struct i915_request *
hsw_enable_metric_set(struct i915_perf_stream *stream)
{
struct intel_uncore *uncore = stream->uncore;

Expand Down Expand Up @@ -2406,7 +2412,8 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
}

static int gen8_enable_metric_set(struct i915_perf_stream *stream)
static struct i915_request *
gen8_enable_metric_set(struct i915_perf_stream *stream)
{
struct intel_uncore *uncore = stream->uncore;
struct i915_oa_config *oa_config = stream->oa_config;
Expand Down Expand Up @@ -2448,7 +2455,7 @@ static int gen8_enable_metric_set(struct i915_perf_stream *stream)
*/
ret = lrc_configure_all_contexts(stream, oa_config);
if (ret)
return ret;
return ERR_PTR(ret);

return emit_oa_config(stream, oa_config, oa_context(stream));
}
Expand All @@ -2460,7 +2467,8 @@ static u32 oag_report_ctx_switches(const struct i915_perf_stream *stream)
0 : GEN12_OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS);
}

static int gen12_enable_metric_set(struct i915_perf_stream *stream)
static struct i915_request *
gen12_enable_metric_set(struct i915_perf_stream *stream)
{
struct intel_uncore *uncore = stream->uncore;
struct i915_oa_config *oa_config = stream->oa_config;
Expand Down Expand Up @@ -2491,7 +2499,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream)
*/
ret = gen12_configure_all_contexts(stream, oa_config);
if (ret)
return ret;
return ERR_PTR(ret);

/*
* For Gen12, performance counters are context
Expand All @@ -2501,7 +2509,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream)
if (stream->ctx) {
ret = gen12_configure_oar_context(stream, true);
if (ret)
return ret;
return ERR_PTR(ret);
}

return emit_oa_config(stream, oa_config, oa_context(stream));
Expand Down Expand Up @@ -2696,6 +2704,20 @@ static const struct i915_perf_stream_ops i915_oa_stream_ops = {
.read = i915_oa_read,
};

static int i915_perf_stream_enable_sync(struct i915_perf_stream *stream)
{
struct i915_request *rq;

rq = stream->perf->ops.enable_metric_set(stream);
if (IS_ERR(rq))
return PTR_ERR(rq);

i915_request_wait(rq, 0, MAX_SCHEDULE_TIMEOUT);
i915_request_put(rq);

return 0;
}

/**
* i915_oa_stream_init - validate combined props for OA stream and init
* @stream: An i915 perf stream
Expand Down Expand Up @@ -2829,7 +2851,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
stream->ops = &i915_oa_stream_ops;
perf->exclusive_stream = stream;

ret = perf->ops.enable_metric_set(stream);
ret = i915_perf_stream_enable_sync(stream);
if (ret) {
DRM_DEBUG("Unable to enable metric set\n");
goto err_enable;
Expand Down Expand Up @@ -3147,7 +3169,7 @@ static long i915_perf_config_locked(struct i915_perf_stream *stream,
return -EINVAL;

if (config != stream->oa_config) {
int err;
struct i915_request *rq;

/*
* If OA is bound to a specific context, emit the
Expand All @@ -3158,11 +3180,13 @@ static long i915_perf_config_locked(struct i915_perf_stream *stream,
* When set globally, we use a low priority kernel context,
* so it will effectively take effect when idle.
*/
err = emit_oa_config(stream, config, oa_context(stream));
if (err == 0)
rq = emit_oa_config(stream, config, oa_context(stream));
if (!IS_ERR(rq)) {
config = xchg(&stream->oa_config, config);
else
ret = err;
i915_request_put(rq);
} else {
ret = PTR_ERR(rq);
}
}

i915_oa_config_put(config);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/i915_perf_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ struct i915_oa_ops {
* counter reports being sampled. May apply system constraints such as
* disabling EU clock gating as required.
*/
int (*enable_metric_set)(struct i915_perf_stream *stream);
struct i915_request *
(*enable_metric_set)(struct i915_perf_stream *stream);

/**
* @disable_metric_set: Remove system constraints associated with using
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7757,6 +7757,7 @@ enum {
#define BW_BUDDY1_CTL _MMIO(0x45140)
#define BW_BUDDY2_CTL _MMIO(0x45150)
#define BW_BUDDY_DISABLE REG_BIT(31)
#define BW_BUDDY_TLB_REQ_TIMER_MASK REG_GENMASK(21, 16)

#define BW_BUDDY1_PAGE_MASK _MMIO(0x45144)
#define BW_BUDDY2_PAGE_MASK _MMIO(0x45154)
Expand Down
Loading

0 comments on commit 64c3fd5

Please sign in to comment.