aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/gt/intel_engine_cs.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2020-02-27 08:59:19 +1000
committerDave Airlie <airlied@redhat.com>2020-02-27 09:00:25 +1000
commit4825b61a3d39eceef7db723808103aa60fc24520 (patch)
tree87e1a754aef38ef088a5ec8e1613790c5a17c078 /drivers/gpu/drm/i915/gt/intel_engine_cs.c
parentaaa9d265a21e7c4fcec12b1203cbfa516277e4ad (diff)
parent53e3ca6749186b5c147964bddc4eb47ba8b5f69e (diff)
Merge tag 'drm-intel-next-2020-02-25' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- A backmerge of drm-next solving conflicts on i915/gt/intel_lrc.c - Clean up shadow batch after I915_EXEC_SECURE - Drop assertion that active->fence is unchanged Here goes drm-intel-next-2020-02-25: - A backmerge of drm-next solving conflicts on i915/gt/intel_lrc.c - Clean up shadow batch after I915_EXEC_SECURE - Drop assertion that active->fence is unchanged drm-intel-next-2020-02-24-1: - RC6 fixes - Chris - Add extra slice common debug register - Lionel - Align virtual engines uabi_class/instance with i915_drm.h - Tvrtko - Avoid potential division by zero in computing CS timestamp - Chris - Avoid using various globals - Michal Winiarski, Matt Auld - Break up long lists of GEM object reclaim - Chris - Check that the vma hasn't been closed before we insert it - Chris - Consolidate SDVO HDMI force_dvi handling - Ville - Conversion to new logging and warn macros and functions - Pankaj, Wambul, Chris - DC3CO fixes - Jose - Disable use of hwsp_cacheline for kernel_context - Chris - Display IRQ pre/post uninstall refactor - Jani - Display port sync refactor for robustness and fixes - Ville, Manasi - Do not attempt to reprogram IA/ring frequencies for dgfx - Chris - Drop alpha_support for good in favor of force_probe - Jani - DSI ACPI related fixes and refactors - Vivek, Jani, Rajat - Encoder refactor for flexibility to add more information, especiallly DSI related - Jani, Vandita - Engine workarounds refactor for robustness around resue - Daniele - FBC simplification and tracepoints - Various fixes for build - Jani, Kees Cook, Chris, Zhang Xiaoxu - Fix cmdparser - Chris - Fix DRM_I915_GEM_MMAP_OFFFSET - Chris - Fix i915_request flags - Chris - Fix inconsistency between pfit enable and scaler freeing - Stanislav - Fix inverted warn_on on display code - Chris - Fix modeset locks in sanitize_watermarks - Ville - Fix OA context id overlap with idle context id - Umesh - Fix pipe and vblank enable for MST - Jani - Fix VBT handling for timing parameters - Vandita - Fixes o kernel doc - Chris, Ville - Force full modeset whenever DSC is enabled at probe - Jani - Various GEM locking simplification and fixes - Jani , Chris, Jose - Including some changes in preparation for making GEM execbuf parallel - Chris - Gen11 pcode error codes - Matt Roper - Gen8+ interrupt handler refactor - Chris - Many fixes and improvements around GuC code - Daniele, Michal Wajdeczko - i915 parameters improvements sfor flexible input and better debugability - Chris, Jani - Ice Lake and Elkhart Lake Fixes and workarounds - Matt Roper, Jose, Vivek, Matt Atwood - Improvements on execlists, requests and other areas, fixing hangs and also improving hang detection, recover and debugability - Chris - Also introducing offline GT error capture - Chris - Introduce encoder->compute_config_late() to help MST - Ville - Make dbuf configuration const - Jani - Few misc clean ups - Ville, Chris - Never allow userptr into the new mapping types - Janusz - Poison rings after use and GTT scratch pages - Chris - Protect signaler walk with RCU - Chris - PSR fixes - Jose - Pull sseu context updates under gt - Chris - Read rawclk_freq earlier - Chris - Refactor around VBT handling to allow geting information through the encoder - Jani - Refactor l3cc/mocs availability - Chris - Refactor to use intel_connector over drm_connector - Ville - Remove i915_energy_uJ from debugfs - Tvrtko - Remove lite restore defines - Mika Kuoppala - Remove prefault_disable modparam - Chris - Many selftests fixes and improvements - Chris - Set intel_dp_set_m_n() for MST slaves - Jose - Simplify hot plug pin handling and other fixes around pin and polled modes - Ville - Skip CPU synchronization on dma-buf attachments - chris - Skip global serialization of clear_range for bxt vtd - Chris - Skip rmw for marked register - Chris - Some other GEM Fixes - Chris - Some small changes for satisfying static code analysis - Colin, Chris - Suppress warnings for unused debugging locals - Tiger Lake enabling, including re-enable -f RPS, workarounds and other display fixes and changes - Chris, Matt Roper, Mika Kuoppala, Anshuman, Jose, Radhakrishna, Rafael. - Track hw reported context runtime - Tvrtko - Update bug filling URL - Jani - Use async bind for PIN_USER into bsw/bxt ggtt - Chris - Use the kernel_context to measuer the breadcrumb size - Chris - Userptr fixes and robustness for big pages - Matt Auld - Various Display refactors and clean-ups, specially around logs and use of drm_i915_private - Jani, Ville - Various display refactors and fixes, especially around cdclk, modeset, and encoder - Chris, Jani - Various eDP/DP fixes around DPCD - Lyude - Various fixes and refactors for better Display watermark handling - Ville, Stanislav - Various other display refactors - Ville - Various refactor for better handling of display plane states - Ville - Wean off drm_pci_alloc/drm_pci_free - Chris - Correctly terminate connector iteration- Ville - Downgrade gen7 (ivb, byt, hsw) back to aliasing-ppgtt - Chris Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200225185853.GA3282832@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/gt/intel_engine_cs.c')
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_cs.c145
1 files changed, 99 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 06ff7695fa29..119c9cb24fd4 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -35,6 +35,7 @@
#include "intel_engine_user.h"
#include "intel_gt.h"
#include "intel_gt_requests.h"
+#include "intel_gt_pm.h"
#include "intel_lrc.h"
#include "intel_reset.h"
#include "intel_ring.h"
@@ -199,10 +200,10 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class)
* out in the wash.
*/
cxt_size = intel_uncore_read(uncore, CXT_SIZE) + 1;
- DRM_DEBUG_DRIVER("gen%d CXT_SIZE = %d bytes [0x%08x]\n",
- INTEL_GEN(gt->i915),
- cxt_size * 64,
- cxt_size - 1);
+ drm_dbg(&gt->i915->drm,
+ "gen%d CXT_SIZE = %d bytes [0x%08x]\n",
+ INTEL_GEN(gt->i915), cxt_size * 64,
+ cxt_size - 1);
return round_up(cxt_size * 64, PAGE_SIZE);
case 3:
case 2:
@@ -392,8 +393,24 @@ void intel_engines_release(struct intel_gt *gt)
struct intel_engine_cs *engine;
enum intel_engine_id id;
+ /*
+ * Before we release the resources held by engine, we must be certain
+ * that the HW is no longer accessing them -- having the GPU scribble
+ * to or read from a page being used for something else causes no end
+ * of fun.
+ *
+ * The GPU should be reset by this point, but assume the worst just
+ * in case we aborted before completely initialising the engines.
+ */
+ GEM_BUG_ON(intel_gt_pm_is_awake(gt));
+ if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
+ __intel_gt_reset(gt, ALL_ENGINES);
+
/* Decouple the backend; but keep the layout for late GPU resets */
for_each_engine(engine, gt, id) {
+ intel_wakeref_wait_for_idle(&engine->wakeref);
+ GEM_BUG_ON(intel_engine_pm_is_awake(engine));
+
if (!engine->release)
continue;
@@ -432,9 +449,9 @@ int intel_engines_init_mmio(struct intel_gt *gt)
unsigned int i;
int err;
- WARN_ON(engine_mask == 0);
- WARN_ON(engine_mask &
- GENMASK(BITS_PER_TYPE(mask) - 1, I915_NUM_ENGINES));
+ drm_WARN_ON(&i915->drm, engine_mask == 0);
+ drm_WARN_ON(&i915->drm, engine_mask &
+ GENMASK(BITS_PER_TYPE(mask) - 1, I915_NUM_ENGINES));
if (i915_inject_probe_failure(i915))
return -ENODEV;
@@ -455,7 +472,7 @@ int intel_engines_init_mmio(struct intel_gt *gt)
* are added to the driver by a warning and disabling the forgotten
* engines.
*/
- if (WARN_ON(mask != engine_mask))
+ if (drm_WARN_ON(&i915->drm, mask != engine_mask))
device_info->engine_mask = mask;
RUNTIME_INFO(i915)->num_engines = hweight32(mask);
@@ -510,7 +527,6 @@ static int pin_ggtt_status_page(struct intel_engine_cs *engine,
{
unsigned int flags;
- flags = PIN_GLOBAL;
if (!HAS_LLC(engine->i915) && i915_ggtt_has_aperture(engine->gt->ggtt))
/*
* On g33, we cannot place HWS above 256MiB, so
@@ -523,11 +539,11 @@ static int pin_ggtt_status_page(struct intel_engine_cs *engine,
* above the mappable region (even though we never
* actually map it).
*/
- flags |= PIN_MAPPABLE;
+ flags = PIN_MAPPABLE;
else
- flags |= PIN_HIGH;
+ flags = PIN_HIGH;
- return i915_vma_pin(vma, 0, 0, flags);
+ return i915_ggtt_pin(vma, 0, flags);
}
static int init_status_page(struct intel_engine_cs *engine)
@@ -546,7 +562,8 @@ static int init_status_page(struct intel_engine_cs *engine)
*/
obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE);
if (IS_ERR(obj)) {
- DRM_ERROR("Failed to allocate status page\n");
+ drm_err(&engine->i915->drm,
+ "Failed to allocate status page\n");
return PTR_ERR(obj);
}
@@ -614,15 +631,15 @@ static int engine_setup_common(struct intel_engine_cs *engine)
struct measure_breadcrumb {
struct i915_request rq;
- struct intel_timeline timeline;
struct intel_ring ring;
u32 cs[1024];
};
-static int measure_breadcrumb_dw(struct intel_engine_cs *engine)
+static int measure_breadcrumb_dw(struct intel_context *ce)
{
+ struct intel_engine_cs *engine = ce->engine;
struct measure_breadcrumb *frame;
- int dw = -ENOMEM;
+ int dw;
GEM_BUG_ON(!engine->gt->scratch);
@@ -630,39 +647,27 @@ static int measure_breadcrumb_dw(struct intel_engine_cs *engine)
if (!frame)
return -ENOMEM;
- if (intel_timeline_init(&frame->timeline,
- engine->gt,
- engine->status_page.vma))
- goto out_frame;
-
- mutex_lock(&frame->timeline.mutex);
+ frame->rq.i915 = engine->i915;
+ frame->rq.engine = engine;
+ frame->rq.context = ce;
+ rcu_assign_pointer(frame->rq.timeline, ce->timeline);
frame->ring.vaddr = frame->cs;
frame->ring.size = sizeof(frame->cs);
frame->ring.effective_size = frame->ring.size;
intel_ring_update_space(&frame->ring);
-
- frame->rq.i915 = engine->i915;
- frame->rq.engine = engine;
frame->rq.ring = &frame->ring;
- rcu_assign_pointer(frame->rq.timeline, &frame->timeline);
-
- dw = intel_timeline_pin(&frame->timeline);
- if (dw < 0)
- goto out_timeline;
+ mutex_lock(&ce->timeline->mutex);
spin_lock_irq(&engine->active.lock);
+
dw = engine->emit_fini_breadcrumb(&frame->rq, frame->cs) - frame->cs;
+
spin_unlock_irq(&engine->active.lock);
+ mutex_unlock(&ce->timeline->mutex);
GEM_BUG_ON(dw & 1); /* RING_TAIL must be qword aligned */
- intel_timeline_unpin(&frame->timeline);
-
-out_timeline:
- mutex_unlock(&frame->timeline.mutex);
- intel_timeline_fini(&frame->timeline);
-out_frame:
kfree(frame);
return dw;
}
@@ -737,12 +742,6 @@ static int engine_init_common(struct intel_engine_cs *engine)
engine->set_default_submission(engine);
- ret = measure_breadcrumb_dw(engine);
- if (ret < 0)
- return ret;
-
- engine->emit_fini_breadcrumb_dw = ret;
-
/*
* We may need to do things with the shrinker which
* require us to immediately switch back to the default
@@ -755,9 +754,18 @@ static int engine_init_common(struct intel_engine_cs *engine)
if (IS_ERR(ce))
return PTR_ERR(ce);
+ ret = measure_breadcrumb_dw(ce);
+ if (ret < 0)
+ goto err_context;
+
+ engine->emit_fini_breadcrumb_dw = ret;
engine->kernel_context = ce;
return 0;
+
+err_context:
+ intel_context_put(ce);
+ return ret;
}
int intel_engines_init(struct intel_gt *gt)
@@ -824,6 +832,20 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
intel_wa_list_free(&engine->whitelist);
}
+/**
+ * intel_engine_resume - re-initializes the HW state of the engine
+ * @engine: Engine to resume.
+ *
+ * Returns zero on success or an error code on failure.
+ */
+int intel_engine_resume(struct intel_engine_cs *engine)
+{
+ intel_engine_apply_workarounds(engine);
+ intel_engine_apply_whitelist(engine);
+
+ return engine->resume(engine);
+}
+
u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
{
struct drm_i915_private *i915 = engine->i915;
@@ -982,6 +1004,12 @@ void intel_engine_get_instdone(const struct intel_engine_cs *engine,
instdone->slice_common =
intel_uncore_read(uncore, GEN7_SC_INSTDONE);
+ if (INTEL_GEN(i915) >= 12) {
+ instdone->slice_common_extra[0] =
+ intel_uncore_read(uncore, GEN12_SC_INSTDONE_EXTRA);
+ instdone->slice_common_extra[1] =
+ intel_uncore_read(uncore, GEN12_SC_INSTDONE_EXTRA2);
+ }
for_each_instdone_slice_subslice(i915, sseu, slice, subslice) {
instdone->sampler[slice][subslice] =
read_subslice_reg(engine, slice, subslice,
@@ -1276,8 +1304,14 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
}
if (INTEL_GEN(dev_priv) >= 6) {
- drm_printf(m, "\tRING_IMR: %08x\n",
+ drm_printf(m, "\tRING_IMR: 0x%08x\n",
ENGINE_READ(engine, RING_IMR));
+ drm_printf(m, "\tRING_ESR: 0x%08x\n",
+ ENGINE_READ(engine, RING_ESR));
+ drm_printf(m, "\tRING_EMR: 0x%08x\n",
+ ENGINE_READ(engine, RING_EMR));
+ drm_printf(m, "\tRING_EIR: 0x%08x\n",
+ ENGINE_READ(engine, RING_EIR));
}
addr = intel_engine_get_active_head(engine);
@@ -1342,7 +1376,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
execlists_active_lock_bh(execlists);
rcu_read_lock();
for (port = execlists->active; (rq = *port); port++) {
- char hdr[80];
+ char hdr[160];
int len;
len = snprintf(hdr, sizeof(hdr),
@@ -1352,10 +1386,12 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
struct intel_timeline *tl = get_timeline(rq);
len += snprintf(hdr + len, sizeof(hdr) - len,
- "ring:{start:%08x, hwsp:%08x, seqno:%08x}, ",
+ "ring:{start:%08x, hwsp:%08x, seqno:%08x, runtime:%llums}, ",
i915_ggtt_offset(rq->ring->vma),
tl ? tl->hwsp_offset : 0,
- hwsp_seqno(rq));
+ hwsp_seqno(rq),
+ DIV_ROUND_CLOSEST_ULL(intel_context_get_total_runtime_ns(rq->context),
+ 1000 * 1000));
if (tl)
intel_timeline_put(tl);
@@ -1657,6 +1693,23 @@ intel_engine_find_active_request(struct intel_engine_cs *engine)
* we only care about the snapshot of this moment.
*/
lockdep_assert_held(&engine->active.lock);
+
+ rcu_read_lock();
+ request = execlists_active(&engine->execlists);
+ if (request) {
+ struct intel_timeline *tl = request->context->timeline;
+
+ list_for_each_entry_from_reverse(request, &tl->requests, link) {
+ if (i915_request_completed(request))
+ break;
+
+ active = request;
+ }
+ }
+ rcu_read_unlock();
+ if (active)
+ return active;
+
list_for_each_entry(request, &engine->active.requests, sched.link) {
if (i915_request_completed(request))
continue;