Merge tag 'drm-intel-next-2017-12-01' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
[airlied: fix conflict in intel_dsi.c] drm-intel-next-2017-12-01: - Init clock gate fix (Ville) - Execlists event handling corrections (Chris, Michel) - Improvements on GPU Cache invalidation and context switch (Chris) - More perf OA changes (Lionel) - More selftests improvements and fixes (Chris, Matthew) - Clean-up on modules parameters (Chris) - Clean-up around old ringbuffer submission and hw semaphore on old platforms (Chris) - More Cannonlake stabilization effort (David, James) - Display planes clean-up and improvements (Ville) - New PMU interface for perf queries... (Tvrtko) - ... and other subsequent PMU changes and fixes (Tvrtko, Chris) - Remove success dmesg noise from rotation (Chris) - New DMC for Kabylake (Anusha) - Fixes around atomic commits (Daniel) - GuC updates and fixes (Sagar, Michal, Chris) - Couple gmbus/i2c fixes (Ville) - Use exponential backoff for all our wait_for() (Chris) - Fixes for i915/fbdev (Chris) - Backlight fixes (Arnd) - Updates on shrinker (Chris) - Make Hotplug enable more robuts (Chris) - Disable huge pages (TPH) on lack of a needed workaround (Joonas) - New GuC images for SKL, KBL, BXT (Sagar) - Add HW Workaround for Geminilake performance (Valtteri) - Fixes for PPS timings (Imre) - More IPS fixes (Maarten) - Many fixes for Display Port on gen2-gen4 (Ville) - Retry GPU reset making the recover from hang more robust (Chris) * tag 'drm-intel-next-2017-12-01' of git://anongit.freedesktop.org/drm/drm-intel: (101 commits) drm/i915: Update DRIVER_DATE to 20171201 drm/i915/cnl: Mask previous DDI - PLL mapping drm/i915: Remove unsafe i915.enable_rc6 drm/i915: Sleep and retry a GPU reset if at first we don't succeed drm/i915: Interlaced DP output doesn't work on VLV/CHV drm/i915: Pass crtc state to intel_pipe_{enable,disable}() drm/i915: Wait for pipe to start on i830 as well drm/i915: Fix vblank timestamp/frame counter jumps on gen2 drm/i915: Fix deadlock in i830_disable_pipe() drm/i915: Fix has_audio readout for DDI A drm/i915: Don't add the "force audio" property to DP connectors that don't support audio drm/i915: Disable DP audio for g4x drm/i915/selftests: Wake the device before executing requests on the GPU drm/i915: Set fake_vma.size as well as fake_vma.node.size for capture drm/i915: Tidy up signed/unsigned comparison drm/i915: Enable IPS with only sprite plane visible too, v4. drm/i915: Make ips_enabled a property depending on whether IPS is enabled, v3. drm/i915: Avoid PPS HW/SW state mismatch due to rounding drm/i915: Skip switch-to-kernel-context on suspend when wedged drm/i915/glk: Apply WaProgramL3SqcReg1DefaultForPerf for GLK too ...
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "i915_gem_batch_pool.h"
|
||||
#include "i915_gem_request.h"
|
||||
#include "i915_gem_timeline.h"
|
||||
#include "i915_pmu.h"
|
||||
#include "i915_selftest.h"
|
||||
|
||||
struct drm_printer;
|
||||
@@ -47,16 +48,6 @@ struct intel_hw_status_page {
|
||||
/* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
|
||||
* do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
|
||||
*/
|
||||
#define gen8_semaphore_seqno_size sizeof(uint64_t)
|
||||
#define GEN8_SEMAPHORE_OFFSET(__from, __to) \
|
||||
(((__from) * I915_NUM_ENGINES + (__to)) * gen8_semaphore_seqno_size)
|
||||
#define GEN8_SIGNAL_OFFSET(__ring, to) \
|
||||
(dev_priv->semaphore->node.start + \
|
||||
GEN8_SEMAPHORE_OFFSET((__ring)->id, (to)))
|
||||
#define GEN8_WAIT_OFFSET(__ring, from) \
|
||||
(dev_priv->semaphore->node.start + \
|
||||
GEN8_SEMAPHORE_OFFSET(from, (__ring)->id))
|
||||
|
||||
enum intel_engine_hangcheck_action {
|
||||
ENGINE_IDLE = 0,
|
||||
ENGINE_WAIT,
|
||||
@@ -252,6 +243,7 @@ struct intel_engine_execlists {
|
||||
unsigned int active;
|
||||
#define EXECLISTS_ACTIVE_USER 0
|
||||
#define EXECLISTS_ACTIVE_PREEMPT 1
|
||||
#define EXECLISTS_ACTIVE_HWACK 2
|
||||
|
||||
/**
|
||||
* @port_mask: number of execlist ports - 1
|
||||
@@ -348,6 +340,43 @@ struct intel_engine_cs {
|
||||
I915_SELFTEST_DECLARE(bool mock : 1);
|
||||
} breadcrumbs;
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @enable: Bitmask of enable sample events on this engine.
|
||||
*
|
||||
* Bits correspond to sample event types, for instance
|
||||
* I915_SAMPLE_QUEUED is bit 0 etc.
|
||||
*/
|
||||
u32 enable;
|
||||
/**
|
||||
* @enable_count: Reference count for the enabled samplers.
|
||||
*
|
||||
* Index number corresponds to the bit number from @enable.
|
||||
*/
|
||||
unsigned int enable_count[I915_PMU_SAMPLE_BITS];
|
||||
/**
|
||||
* @sample: Counter values for sampling events.
|
||||
*
|
||||
* Our internal timer stores the current counters in this field.
|
||||
*/
|
||||
#define I915_ENGINE_SAMPLE_MAX (I915_SAMPLE_SEMA + 1)
|
||||
struct i915_pmu_sample sample[I915_ENGINE_SAMPLE_MAX];
|
||||
/**
|
||||
* @busy_stats: Has enablement of engine stats tracking been
|
||||
* requested.
|
||||
*/
|
||||
bool busy_stats;
|
||||
/**
|
||||
* @disable_busy_stats: Work item for busy stats disabling.
|
||||
*
|
||||
* Same as with @enable_busy_stats action, with the difference
|
||||
* that we delay it in case there are rapid enable-disable
|
||||
* actions, which can happen during tool startup (like perf
|
||||
* stat).
|
||||
*/
|
||||
struct delayed_work disable_busy_stats;
|
||||
} pmu;
|
||||
|
||||
/*
|
||||
* A pool of objects to use as shadow copies of client batch buffers
|
||||
* when the command parser is enabled. Prevents the client from
|
||||
@@ -467,18 +496,15 @@ struct intel_engine_cs {
|
||||
* ie. transpose of f(x, y)
|
||||
*/
|
||||
struct {
|
||||
union {
|
||||
#define GEN6_SEMAPHORE_LAST VECS_HW
|
||||
#define GEN6_NUM_SEMAPHORES (GEN6_SEMAPHORE_LAST + 1)
|
||||
#define GEN6_SEMAPHORES_MASK GENMASK(GEN6_SEMAPHORE_LAST, 0)
|
||||
struct {
|
||||
/* our mbox written by others */
|
||||
u32 wait[GEN6_NUM_SEMAPHORES];
|
||||
/* mboxes this ring signals to */
|
||||
i915_reg_t signal[GEN6_NUM_SEMAPHORES];
|
||||
} mbox;
|
||||
u64 signal_ggtt[I915_NUM_ENGINES];
|
||||
};
|
||||
struct {
|
||||
/* our mbox written by others */
|
||||
u32 wait[GEN6_NUM_SEMAPHORES];
|
||||
/* mboxes this ring signals to */
|
||||
i915_reg_t signal[GEN6_NUM_SEMAPHORES];
|
||||
} mbox;
|
||||
|
||||
/* AKA wait() */
|
||||
int (*sync_to)(struct drm_i915_gem_request *req,
|
||||
@@ -506,13 +532,16 @@ struct intel_engine_cs {
|
||||
* stream (ring).
|
||||
*/
|
||||
struct i915_gem_context *legacy_active_context;
|
||||
struct i915_hw_ppgtt *legacy_active_ppgtt;
|
||||
|
||||
/* status_notifier: list of callbacks for context-switch changes */
|
||||
struct atomic_notifier_head context_status_notifier;
|
||||
|
||||
struct intel_engine_hangcheck hangcheck;
|
||||
|
||||
bool needs_cmd_parser;
|
||||
#define I915_ENGINE_NEEDS_CMD_PARSER BIT(0)
|
||||
#define I915_ENGINE_SUPPORTS_STATS BIT(1)
|
||||
unsigned int flags;
|
||||
|
||||
/*
|
||||
* Table of commands the command parser needs to know about
|
||||
@@ -537,8 +566,50 @@ struct intel_engine_cs {
|
||||
* certain bits to encode the command length in the header).
|
||||
*/
|
||||
u32 (*get_cmd_length_mask)(u32 cmd_header);
|
||||
|
||||
struct {
|
||||
/**
|
||||
* @lock: Lock protecting the below fields.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
/**
|
||||
* @enabled: Reference count indicating number of listeners.
|
||||
*/
|
||||
unsigned int enabled;
|
||||
/**
|
||||
* @active: Number of contexts currently scheduled in.
|
||||
*/
|
||||
unsigned int active;
|
||||
/**
|
||||
* @enabled_at: Timestamp when busy stats were enabled.
|
||||
*/
|
||||
ktime_t enabled_at;
|
||||
/**
|
||||
* @start: Timestamp of the last idle to active transition.
|
||||
*
|
||||
* Idle is defined as active == 0, active is active > 0.
|
||||
*/
|
||||
ktime_t start;
|
||||
/**
|
||||
* @total: Total time this engine was busy.
|
||||
*
|
||||
* Accumulated time not counting the most recent block in cases
|
||||
* where engine is currently busy (active > 0).
|
||||
*/
|
||||
ktime_t total;
|
||||
} stats;
|
||||
};
|
||||
|
||||
static inline bool intel_engine_needs_cmd_parser(struct intel_engine_cs *engine)
|
||||
{
|
||||
return engine->flags & I915_ENGINE_NEEDS_CMD_PARSER;
|
||||
}
|
||||
|
||||
static inline bool intel_engine_supports_stats(struct intel_engine_cs *engine)
|
||||
{
|
||||
return engine->flags & I915_ENGINE_SUPPORTS_STATS;
|
||||
}
|
||||
|
||||
static inline void
|
||||
execlists_set_active(struct intel_engine_execlists *execlists,
|
||||
unsigned int bit)
|
||||
@@ -939,4 +1010,67 @@ bool intel_engine_can_store_dword(struct intel_engine_cs *engine);
|
||||
|
||||
void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *p);
|
||||
|
||||
struct intel_engine_cs *
|
||||
intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
|
||||
|
||||
static inline void intel_engine_context_in(struct intel_engine_cs *engine)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (READ_ONCE(engine->stats.enabled) == 0)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&engine->stats.lock, flags);
|
||||
|
||||
if (engine->stats.enabled > 0) {
|
||||
if (engine->stats.active++ == 0)
|
||||
engine->stats.start = ktime_get();
|
||||
GEM_BUG_ON(engine->stats.active == 0);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&engine->stats.lock, flags);
|
||||
}
|
||||
|
||||
static inline void intel_engine_context_out(struct intel_engine_cs *engine)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (READ_ONCE(engine->stats.enabled) == 0)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&engine->stats.lock, flags);
|
||||
|
||||
if (engine->stats.enabled > 0) {
|
||||
ktime_t last;
|
||||
|
||||
if (engine->stats.active && --engine->stats.active == 0) {
|
||||
/*
|
||||
* Decrement the active context count and in case GPU
|
||||
* is now idle add up to the running total.
|
||||
*/
|
||||
last = ktime_sub(ktime_get(), engine->stats.start);
|
||||
|
||||
engine->stats.total = ktime_add(engine->stats.total,
|
||||
last);
|
||||
} else if (engine->stats.active == 0) {
|
||||
/*
|
||||
* After turning on engine stats, context out might be
|
||||
* the first event in which case we account from the
|
||||
* time stats gathering was turned on.
|
||||
*/
|
||||
last = ktime_sub(ktime_get(), engine->stats.enabled_at);
|
||||
|
||||
engine->stats.total = ktime_add(engine->stats.total,
|
||||
last);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&engine->stats.lock, flags);
|
||||
}
|
||||
|
||||
int intel_enable_engine_stats(struct intel_engine_cs *engine);
|
||||
void intel_disable_engine_stats(struct intel_engine_cs *engine);
|
||||
|
||||
ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine);
|
||||
|
||||
#endif /* _INTEL_RINGBUFFER_H_ */
|
||||
|
Reference in New Issue
Block a user