提交 82e50ec8 编写于 作者: D Dave Airlie

Merge tag 'drm-intel-fixes-2019-12-12' of...

Merge tag 'drm-intel-fixes-2019-12-12' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

- Fix user reported issue #673: GPU hang on transition to idle
- Avoid corruption on the top of the screen on GLK+ by disabling FBC
- Fix non-privileged access to OA on Tigerlake
- Fix HDCP code not to touch global state when just computing commit
- Fix CI splat by saving irqstate around virtual_context_destroy
- Serialise context retirement possibly on another CPU
Signed-off-by: NDave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212100759.GA22260@jlahtine-desk.ger.corp.intel.com
...@@ -3986,6 +3986,7 @@ static void intel_enable_ddi(struct intel_encoder *encoder, ...@@ -3986,6 +3986,7 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
if (conn_state->content_protection == if (conn_state->content_protection ==
DRM_MODE_CONTENT_PROTECTION_DESIRED) DRM_MODE_CONTENT_PROTECTION_DESIRED)
intel_hdcp_enable(to_intel_connector(conn_state->connector), intel_hdcp_enable(to_intel_connector(conn_state->connector),
crtc_state->cpu_transcoder,
(u8)conn_state->hdcp_content_type); (u8)conn_state->hdcp_content_type);
} }
...@@ -4089,7 +4090,9 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder, ...@@ -4089,7 +4090,9 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
if (conn_state->content_protection == if (conn_state->content_protection ==
DRM_MODE_CONTENT_PROTECTION_DESIRED || DRM_MODE_CONTENT_PROTECTION_DESIRED ||
content_protection_type_changed) content_protection_type_changed)
intel_hdcp_enable(connector, (u8)conn_state->hdcp_content_type); intel_hdcp_enable(connector,
crtc_state->cpu_transcoder,
(u8)conn_state->hdcp_content_type);
} }
static void static void
......
...@@ -2414,9 +2414,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, ...@@ -2414,9 +2414,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
intel_psr_compute_config(intel_dp, pipe_config); intel_psr_compute_config(intel_dp, pipe_config);
intel_hdcp_transcoder_config(intel_connector,
pipe_config->cpu_transcoder);
return 0; return 0;
} }
......
...@@ -1284,7 +1284,7 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) ...@@ -1284,7 +1284,7 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
return 0; return 0;
/* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */ /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */
if (IS_GEMINILAKE(dev_priv)) if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
return 0; return 0;
if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
......
...@@ -1821,23 +1821,6 @@ enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder) ...@@ -1821,23 +1821,6 @@ enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
} }
} }
void intel_hdcp_transcoder_config(struct intel_connector *connector,
enum transcoder cpu_transcoder)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
if (!hdcp->shim)
return;
if (INTEL_GEN(dev_priv) >= 12) {
mutex_lock(&hdcp->mutex);
hdcp->cpu_transcoder = cpu_transcoder;
hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder);
mutex_unlock(&hdcp->mutex);
}
}
static inline int initialize_hdcp_port_data(struct intel_connector *connector, static inline int initialize_hdcp_port_data(struct intel_connector *connector,
const struct intel_hdcp_shim *shim) const struct intel_hdcp_shim *shim)
{ {
...@@ -1959,8 +1942,10 @@ int intel_hdcp_init(struct intel_connector *connector, ...@@ -1959,8 +1942,10 @@ int intel_hdcp_init(struct intel_connector *connector,
return 0; return 0;
} }
int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) int intel_hdcp_enable(struct intel_connector *connector,
enum transcoder cpu_transcoder, u8 content_type)
{ {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp; struct intel_hdcp *hdcp = &connector->hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
int ret = -EINVAL; int ret = -EINVAL;
...@@ -1972,6 +1957,11 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type) ...@@ -1972,6 +1957,11 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
hdcp->content_type = content_type; hdcp->content_type = content_type;
if (INTEL_GEN(dev_priv) >= 12) {
hdcp->cpu_transcoder = cpu_transcoder;
hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder);
}
/* /*
* Considering that HDCP2.2 is more secure than HDCP1.4, If the setup * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
* is capable of HDCP2.2, it is preferred to use HDCP2.2. * is capable of HDCP2.2, it is preferred to use HDCP2.2.
......
...@@ -21,11 +21,10 @@ enum transcoder; ...@@ -21,11 +21,10 @@ enum transcoder;
void intel_hdcp_atomic_check(struct drm_connector *connector, void intel_hdcp_atomic_check(struct drm_connector *connector,
struct drm_connector_state *old_state, struct drm_connector_state *old_state,
struct drm_connector_state *new_state); struct drm_connector_state *new_state);
void intel_hdcp_transcoder_config(struct intel_connector *connector,
enum transcoder cpu_transcoder);
int intel_hdcp_init(struct intel_connector *connector, int intel_hdcp_init(struct intel_connector *connector,
const struct intel_hdcp_shim *hdcp_shim); const struct intel_hdcp_shim *hdcp_shim);
int intel_hdcp_enable(struct intel_connector *connector, u8 content_type); int intel_hdcp_enable(struct intel_connector *connector,
enum transcoder cpu_transcoder, u8 content_type);
int intel_hdcp_disable(struct intel_connector *connector); int intel_hdcp_disable(struct intel_connector *connector);
bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
bool intel_hdcp_capable(struct intel_connector *connector); bool intel_hdcp_capable(struct intel_connector *connector);
......
...@@ -2489,9 +2489,6 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, ...@@ -2489,9 +2489,6 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
return -EINVAL; return -EINVAL;
} }
intel_hdcp_transcoder_config(intel_hdmi->attached_connector,
pipe_config->cpu_transcoder);
return 0; return 0;
} }
......
...@@ -845,12 +845,6 @@ static const u8 *reg_offsets(const struct intel_engine_cs *engine) ...@@ -845,12 +845,6 @@ static const u8 *reg_offsets(const struct intel_engine_cs *engine)
} }
} }
static void unwind_wa_tail(struct i915_request *rq)
{
rq->tail = intel_ring_wrap(rq->ring, rq->wa_tail - WA_TAIL_BYTES);
assert_ring_tail_valid(rq->ring, rq->tail);
}
static struct i915_request * static struct i915_request *
__unwind_incomplete_requests(struct intel_engine_cs *engine) __unwind_incomplete_requests(struct intel_engine_cs *engine)
{ {
...@@ -863,12 +857,10 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine) ...@@ -863,12 +857,10 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
list_for_each_entry_safe_reverse(rq, rn, list_for_each_entry_safe_reverse(rq, rn,
&engine->active.requests, &engine->active.requests,
sched.link) { sched.link) {
if (i915_request_completed(rq)) if (i915_request_completed(rq))
continue; /* XXX */ continue; /* XXX */
__i915_request_unsubmit(rq); __i915_request_unsubmit(rq);
unwind_wa_tail(rq);
/* /*
* Push the request back into the queue for later resubmission. * Push the request back into the queue for later resubmission.
...@@ -1161,13 +1153,29 @@ execlists_schedule_out(struct i915_request *rq) ...@@ -1161,13 +1153,29 @@ execlists_schedule_out(struct i915_request *rq)
i915_request_put(rq); i915_request_put(rq);
} }
static u64 execlists_update_context(const struct i915_request *rq) static u64 execlists_update_context(struct i915_request *rq)
{ {
struct intel_context *ce = rq->hw_context; struct intel_context *ce = rq->hw_context;
u64 desc; u64 desc = ce->lrc_desc;
u32 tail;
ce->lrc_reg_state[CTX_RING_TAIL] = /*
intel_ring_set_tail(rq->ring, rq->tail); * WaIdleLiteRestore:bdw,skl
*
* We should never submit the context with the same RING_TAIL twice
* just in case we submit an empty ring, which confuses the HW.
*
* We append a couple of NOOPs (gen8_emit_wa_tail) after the end of
* the normal request to be able to always advance the RING_TAIL on
* subsequent resubmissions (for lite restore). Should that fail us,
* and we try and submit the same tail again, force the context
* reload.
*/
tail = intel_ring_set_tail(rq->ring, rq->tail);
if (unlikely(ce->lrc_reg_state[CTX_RING_TAIL] == tail))
desc |= CTX_DESC_FORCE_RESTORE;
ce->lrc_reg_state[CTX_RING_TAIL] = tail;
rq->tail = rq->wa_tail;
/* /*
* Make sure the context image is complete before we submit it to HW. * Make sure the context image is complete before we submit it to HW.
...@@ -1186,13 +1194,11 @@ static u64 execlists_update_context(const struct i915_request *rq) ...@@ -1186,13 +1194,11 @@ static u64 execlists_update_context(const struct i915_request *rq)
*/ */
mb(); mb();
desc = ce->lrc_desc;
ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE;
/* Wa_1607138340:tgl */ /* Wa_1607138340:tgl */
if (IS_TGL_REVID(rq->i915, TGL_REVID_A0, TGL_REVID_A0)) if (IS_TGL_REVID(rq->i915, TGL_REVID_A0, TGL_REVID_A0))
desc |= CTX_DESC_FORCE_RESTORE; desc |= CTX_DESC_FORCE_RESTORE;
ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE;
return desc; return desc;
} }
...@@ -1703,16 +1709,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine) ...@@ -1703,16 +1709,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
return; return;
} }
/*
* WaIdleLiteRestore:bdw,skl
* Apply the wa NOOPs to prevent
* ring:HEAD == rq:TAIL as we resubmit the
* request. See gen8_emit_fini_breadcrumb() for
* where we prepare the padding after the
* end of the request.
*/
last->tail = last->wa_tail;
} }
} }
...@@ -4120,17 +4116,18 @@ static void virtual_context_destroy(struct kref *kref) ...@@ -4120,17 +4116,18 @@ static void virtual_context_destroy(struct kref *kref)
for (n = 0; n < ve->num_siblings; n++) { for (n = 0; n < ve->num_siblings; n++) {
struct intel_engine_cs *sibling = ve->siblings[n]; struct intel_engine_cs *sibling = ve->siblings[n];
struct rb_node *node = &ve->nodes[sibling->id].rb; struct rb_node *node = &ve->nodes[sibling->id].rb;
unsigned long flags;
if (RB_EMPTY_NODE(node)) if (RB_EMPTY_NODE(node))
continue; continue;
spin_lock_irq(&sibling->active.lock); spin_lock_irqsave(&sibling->active.lock, flags);
/* Detachment is lazily performed in the execlists tasklet */ /* Detachment is lazily performed in the execlists tasklet */
if (!RB_EMPTY_NODE(node)) if (!RB_EMPTY_NODE(node))
rb_erase_cached(node, &sibling->execlists.virtual); rb_erase_cached(node, &sibling->execlists.virtual);
spin_unlock_irq(&sibling->active.lock); spin_unlock_irqrestore(&sibling->active.lock, flags);
} }
GEM_BUG_ON(__tasklet_is_scheduled(&ve->base.execlists.tasklet)); GEM_BUG_ON(__tasklet_is_scheduled(&ve->base.execlists.tasklet));
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "gem/i915_gem_context.h" #include "gem/i915_gem_context.h"
#include "gem/i915_gem_ioctls.h" #include "gem/i915_gem_ioctls.h"
#include "gem/i915_gem_pm.h" #include "gem/i915_gem_pm.h"
#include "gt/intel_context.h"
#include "gt/intel_engine_user.h" #include "gt/intel_engine_user.h"
#include "gt/intel_gt.h" #include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h" #include "gt/intel_gt_pm.h"
...@@ -1053,6 +1054,18 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, ...@@ -1053,6 +1054,18 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
return err; return err;
} }
static int __intel_context_flush_retire(struct intel_context *ce)
{
struct intel_timeline *tl;
tl = intel_context_timeline_lock(ce);
if (IS_ERR(tl))
return PTR_ERR(tl);
intel_context_timeline_unlock(tl);
return 0;
}
static int __intel_engines_record_defaults(struct intel_gt *gt) static int __intel_engines_record_defaults(struct intel_gt *gt)
{ {
struct i915_request *requests[I915_NUM_ENGINES] = {}; struct i915_request *requests[I915_NUM_ENGINES] = {};
...@@ -1121,13 +1134,20 @@ static int __intel_engines_record_defaults(struct intel_gt *gt) ...@@ -1121,13 +1134,20 @@ static int __intel_engines_record_defaults(struct intel_gt *gt)
if (!rq) if (!rq)
continue; continue;
/* We want to be able to unbind the state from the GGTT */ GEM_BUG_ON(!test_bit(CONTEXT_ALLOC_BIT,
GEM_BUG_ON(intel_context_is_pinned(rq->hw_context)); &rq->hw_context->flags));
state = rq->hw_context->state; state = rq->hw_context->state;
if (!state) if (!state)
continue; continue;
/* Serialise with retirement on another CPU */
err = __intel_context_flush_retire(rq->hw_context);
if (err)
goto out;
/* We want to be able to unbind the state from the GGTT */
GEM_BUG_ON(intel_context_is_pinned(rq->hw_context));
/* /*
* As we will hold a reference to the logical state, it will * As we will hold a reference to the logical state, it will
* not be torn down with the context, and importantly the * not be torn down with the context, and importantly the
......
...@@ -2078,20 +2078,12 @@ gen8_update_reg_state_unlocked(const struct intel_context *ce, ...@@ -2078,20 +2078,12 @@ gen8_update_reg_state_unlocked(const struct intel_context *ce,
u32 *reg_state = ce->lrc_reg_state; u32 *reg_state = ce->lrc_reg_state;
int i; int i;
if (IS_GEN(stream->perf->i915, 12)) { reg_state[ctx_oactxctrl + 1] =
u32 format = stream->oa_buffer.format; (stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
(stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
GEN8_OA_COUNTER_RESUME;
reg_state[ctx_oactxctrl + 1] = for (i = 0; i < ARRAY_SIZE(flex_regs); i++)
(format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
(stream->oa_config ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0);
} else {
reg_state[ctx_oactxctrl + 1] =
(stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
(stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
GEN8_OA_COUNTER_RESUME;
}
for (i = 0; !!ctx_flexeu0 && i < ARRAY_SIZE(flex_regs); i++)
reg_state[ctx_flexeu0 + i * 2 + 1] = reg_state[ctx_flexeu0 + i * 2 + 1] =
oa_config_flex_reg(stream->oa_config, flex_regs[i]); oa_config_flex_reg(stream->oa_config, flex_regs[i]);
...@@ -2224,34 +2216,51 @@ static int gen8_configure_context(struct i915_gem_context *ctx, ...@@ -2224,34 +2216,51 @@ static int gen8_configure_context(struct i915_gem_context *ctx,
return err; return err;
} }
static int gen12_emit_oar_config(struct intel_context *ce, bool enable) static int gen12_configure_oar_context(struct i915_perf_stream *stream, bool enable)
{ {
struct i915_request *rq; int err;
u32 *cs; struct intel_context *ce = stream->pinned_ctx;
int err = 0; u32 format = stream->oa_buffer.format;
struct flex regs_context[] = {
rq = i915_request_create(ce); {
if (IS_ERR(rq)) GEN8_OACTXCONTROL,
return PTR_ERR(rq); stream->perf->ctx_oactxctrl_offset + 1,
enable ? GEN8_OA_COUNTER_RESUME : 0,
cs = intel_ring_begin(rq, 4); },
if (IS_ERR(cs)) { };
err = PTR_ERR(cs); /* Offsets in regs_lri are not used since this configuration is only
goto out; * applied using LRI. Initialize the correct offsets for posterity.
} */
#define GEN12_OAR_OACONTROL_OFFSET 0x5B0
*cs++ = MI_LOAD_REGISTER_IMM(1); struct flex regs_lri[] = {
*cs++ = i915_mmio_reg_offset(RING_CONTEXT_CONTROL(ce->engine->mmio_base)); {
*cs++ = _MASKED_FIELD(GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE, GEN12_OAR_OACONTROL,
enable ? GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE : 0); GEN12_OAR_OACONTROL_OFFSET + 1,
*cs++ = MI_NOOP; (format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
(enable ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0)
},
{
RING_CONTEXT_CONTROL(ce->engine->mmio_base),
CTX_CONTEXT_CONTROL,
_MASKED_FIELD(GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE,
enable ?
GEN12_CTX_CTRL_OAR_CONTEXT_ENABLE :
0)
},
};
intel_ring_advance(rq, cs); /* Modify the context image of pinned context with regs_context*/
err = intel_context_lock_pinned(ce);
if (err)
return err;
out: err = gen8_modify_context(ce, regs_context, ARRAY_SIZE(regs_context));
i915_request_add(rq); intel_context_unlock_pinned(ce);
if (err)
return err;
return err; /* Apply regs_lri using LRI with pinned context */
return gen8_modify_self(ce, regs_lri, ARRAY_SIZE(regs_lri));
} }
/* /*
...@@ -2277,53 +2286,16 @@ static int gen12_emit_oar_config(struct intel_context *ce, bool enable) ...@@ -2277,53 +2286,16 @@ static int gen12_emit_oar_config(struct intel_context *ce, bool enable)
* per-context OA state. * per-context OA state.
* *
* Note: it's only the RCS/Render context that has any OA state. * Note: it's only the RCS/Render context that has any OA state.
* Note: the first flex register passed must always be R_PWR_CLK_STATE
*/ */
static int lrc_configure_all_contexts(struct i915_perf_stream *stream, static int oa_configure_all_contexts(struct i915_perf_stream *stream,
const struct i915_oa_config *oa_config) struct flex *regs,
size_t num_regs)
{ {
struct drm_i915_private *i915 = stream->perf->i915; struct drm_i915_private *i915 = stream->perf->i915;
/* The MMIO offsets for Flex EU registers aren't contiguous */
const u32 ctx_flexeu0 = stream->perf->ctx_flexeu0_offset;
#define ctx_flexeuN(N) (ctx_flexeu0 + 2 * (N) + 1)
struct flex regs[] = {
{
GEN8_R_PWR_CLK_STATE,
CTX_R_PWR_CLK_STATE,
},
{
IS_GEN(i915, 12) ?
GEN12_OAR_OACONTROL : GEN8_OACTXCONTROL,
stream->perf->ctx_oactxctrl_offset + 1,
},
{ EU_PERF_CNTL0, ctx_flexeuN(0) },
{ EU_PERF_CNTL1, ctx_flexeuN(1) },
{ EU_PERF_CNTL2, ctx_flexeuN(2) },
{ EU_PERF_CNTL3, ctx_flexeuN(3) },
{ EU_PERF_CNTL4, ctx_flexeuN(4) },
{ EU_PERF_CNTL5, ctx_flexeuN(5) },
{ EU_PERF_CNTL6, ctx_flexeuN(6) },
};
#undef ctx_flexeuN
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
struct i915_gem_context *ctx, *cn; struct i915_gem_context *ctx, *cn;
size_t array_size = IS_GEN(i915, 12) ? 2 : ARRAY_SIZE(regs); int err;
int i, err;
if (IS_GEN(i915, 12)) {
u32 format = stream->oa_buffer.format;
regs[1].value =
(format << GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT) |
(oa_config ? GEN12_OAR_OACONTROL_COUNTER_ENABLE : 0);
} else {
regs[1].value =
(stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
(stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
GEN8_OA_COUNTER_RESUME;
}
for (i = 2; !!ctx_flexeu0 && i < array_size; i++)
regs[i].value = oa_config_flex_reg(oa_config, regs[i].reg);
lockdep_assert_held(&stream->perf->lock); lockdep_assert_held(&stream->perf->lock);
...@@ -2353,7 +2325,7 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream, ...@@ -2353,7 +2325,7 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
spin_unlock(&i915->gem.contexts.lock); spin_unlock(&i915->gem.contexts.lock);
err = gen8_configure_context(ctx, regs, array_size); err = gen8_configure_context(ctx, regs, num_regs);
if (err) { if (err) {
i915_gem_context_put(ctx); i915_gem_context_put(ctx);
return err; return err;
...@@ -2378,7 +2350,7 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream, ...@@ -2378,7 +2350,7 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
regs[0].value = intel_sseu_make_rpcs(i915, &ce->sseu); regs[0].value = intel_sseu_make_rpcs(i915, &ce->sseu);
err = gen8_modify_self(ce, regs, array_size); err = gen8_modify_self(ce, regs, num_regs);
if (err) if (err)
return err; return err;
} }
...@@ -2386,6 +2358,56 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream, ...@@ -2386,6 +2358,56 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
return 0; return 0;
} }
static int gen12_configure_all_contexts(struct i915_perf_stream *stream,
const struct i915_oa_config *oa_config)
{
struct flex regs[] = {
{
GEN8_R_PWR_CLK_STATE,
CTX_R_PWR_CLK_STATE,
},
};
return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
}
static int lrc_configure_all_contexts(struct i915_perf_stream *stream,
const struct i915_oa_config *oa_config)
{
/* The MMIO offsets for Flex EU registers aren't contiguous */
const u32 ctx_flexeu0 = stream->perf->ctx_flexeu0_offset;
#define ctx_flexeuN(N) (ctx_flexeu0 + 2 * (N) + 1)
struct flex regs[] = {
{
GEN8_R_PWR_CLK_STATE,
CTX_R_PWR_CLK_STATE,
},
{
GEN8_OACTXCONTROL,
stream->perf->ctx_oactxctrl_offset + 1,
},
{ EU_PERF_CNTL0, ctx_flexeuN(0) },
{ EU_PERF_CNTL1, ctx_flexeuN(1) },
{ EU_PERF_CNTL2, ctx_flexeuN(2) },
{ EU_PERF_CNTL3, ctx_flexeuN(3) },
{ EU_PERF_CNTL4, ctx_flexeuN(4) },
{ EU_PERF_CNTL5, ctx_flexeuN(5) },
{ EU_PERF_CNTL6, ctx_flexeuN(6) },
};
#undef ctx_flexeuN
int i;
regs[1].value =
(stream->period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
(stream->periodic ? GEN8_OA_TIMER_ENABLE : 0) |
GEN8_OA_COUNTER_RESUME;
for (i = 2; i < ARRAY_SIZE(regs); i++)
regs[i].value = oa_config_flex_reg(oa_config, regs[i].reg);
return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs));
}
static int gen8_enable_metric_set(struct i915_perf_stream *stream) static int gen8_enable_metric_set(struct i915_perf_stream *stream)
{ {
struct intel_uncore *uncore = stream->uncore; struct intel_uncore *uncore = stream->uncore;
...@@ -2464,7 +2486,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream) ...@@ -2464,7 +2486,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream)
* to make sure all slices/subslices are ON before writing to NOA * to make sure all slices/subslices are ON before writing to NOA
* registers. * registers.
*/ */
ret = lrc_configure_all_contexts(stream, oa_config); ret = gen12_configure_all_contexts(stream, oa_config);
if (ret) if (ret)
return ret; return ret;
...@@ -2474,8 +2496,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream) ...@@ -2474,8 +2496,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream)
* requested this. * requested this.
*/ */
if (stream->ctx) { if (stream->ctx) {
ret = gen12_emit_oar_config(stream->pinned_ctx, ret = gen12_configure_oar_context(stream, true);
oa_config != NULL);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -2509,11 +2530,11 @@ static void gen12_disable_metric_set(struct i915_perf_stream *stream) ...@@ -2509,11 +2530,11 @@ static void gen12_disable_metric_set(struct i915_perf_stream *stream)
struct intel_uncore *uncore = stream->uncore; struct intel_uncore *uncore = stream->uncore;
/* Reset all contexts' slices/subslices configurations. */ /* Reset all contexts' slices/subslices configurations. */
lrc_configure_all_contexts(stream, NULL); gen12_configure_all_contexts(stream, NULL);
/* disable the context save/restore or OAR counters */ /* disable the context save/restore or OAR counters */
if (stream->ctx) if (stream->ctx)
gen12_emit_oar_config(stream->pinned_ctx, false); gen12_configure_oar_context(stream, false);
/* Make sure we disable noa to save power. */ /* Make sure we disable noa to save power. */
intel_uncore_rmw(uncore, RPM_CONFIG1, GEN10_GT_NOA_ENABLE, 0); intel_uncore_rmw(uncore, RPM_CONFIG1, GEN10_GT_NOA_ENABLE, 0);
...@@ -2713,7 +2734,8 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream, ...@@ -2713,7 +2734,8 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return -EINVAL; return -EINVAL;
} }
if (!(props->sample_flags & SAMPLE_OA_REPORT)) { if (!(props->sample_flags & SAMPLE_OA_REPORT) &&
(INTEL_GEN(perf->i915) < 12 || !stream->ctx)) {
DRM_DEBUG("Only OA report sampling supported\n"); DRM_DEBUG("Only OA report sampling supported\n");
return -EINVAL; return -EINVAL;
} }
...@@ -2745,7 +2767,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream, ...@@ -2745,7 +2767,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
format_size = perf->oa_formats[props->oa_format].size; format_size = perf->oa_formats[props->oa_format].size;
stream->sample_flags |= SAMPLE_OA_REPORT; stream->sample_flags = props->sample_flags;
stream->sample_size += format_size; stream->sample_size += format_size;
stream->oa_buffer.format_size = format_size; stream->oa_buffer.format_size = format_size;
...@@ -2854,7 +2876,11 @@ void i915_oa_init_reg_state(const struct intel_context *ce, ...@@ -2854,7 +2876,11 @@ void i915_oa_init_reg_state(const struct intel_context *ce,
return; return;
stream = engine->i915->perf.exclusive_stream; stream = engine->i915->perf.exclusive_stream;
if (stream) /*
* For gen12, only CTX_R_PWR_CLK_STATE needs update, but the caller
* is already doing that, so nothing to be done for gen12 here.
*/
if (stream && INTEL_GEN(stream->perf->i915) < 12)
gen8_update_reg_state_unlocked(ce, stream); gen8_update_reg_state_unlocked(ce, stream);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册