diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.h')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 186 |
1 files changed, 102 insertions, 84 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e1f7c97a338a..7c6fab08a2e6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -80,8 +80,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20170619" -#define DRIVER_TIMESTAMP 1497857498 +#define DRIVER_DATE "20170717" +#define DRIVER_TIMESTAMP 1500275179 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions @@ -122,7 +122,7 @@ static inline bool is_fixed16_zero(uint_fixed_16_16_t val) return false; } -static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val) +static inline uint_fixed_16_16_t u32_to_fixed16(uint32_t val) { uint_fixed_16_16_t fp; @@ -132,17 +132,17 @@ static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val) return fp; } -static inline uint32_t fixed_16_16_to_u32_round_up(uint_fixed_16_16_t fp) +static inline uint32_t fixed16_to_u32_round_up(uint_fixed_16_16_t fp) { return DIV_ROUND_UP(fp.val, 1 << 16); } -static inline uint32_t fixed_16_16_to_u32(uint_fixed_16_16_t fp) +static inline uint32_t fixed16_to_u32(uint_fixed_16_16_t fp) { return fp.val >> 16; } -static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1, +static inline uint_fixed_16_16_t min_fixed16(uint_fixed_16_16_t min1, uint_fixed_16_16_t min2) { uint_fixed_16_16_t min; @@ -151,7 +151,7 @@ static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1, return min; } -static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1, +static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1, uint_fixed_16_16_t max2) { uint_fixed_16_16_t max; @@ -160,6 +160,14 @@ static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1, return max; } +static inline uint_fixed_16_16_t clamp_u64_to_fixed16(uint64_t val) +{ + uint_fixed_16_16_t fp; + WARN_ON(val >> 32); + fp.val = clamp_t(uint32_t, val, 0, ~0); + return fp; +} + static inline uint32_t div_round_up_fixed16(uint_fixed_16_16_t val, uint_fixed_16_16_t d) { @@ -170,48 +178,30 @@ static inline uint32_t mul_round_up_u32_fixed16(uint32_t val, uint_fixed_16_16_t mul) { uint64_t intermediate_val; - uint32_t result; intermediate_val = (uint64_t) val * mul.val; intermediate_val = DIV_ROUND_UP_ULL(intermediate_val, 1 << 16); WARN_ON(intermediate_val >> 32); - result = clamp_t(uint32_t, intermediate_val, 0, ~0); - return result; + return clamp_t(uint32_t, intermediate_val, 0, ~0); } static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val, uint_fixed_16_16_t mul) { uint64_t intermediate_val; - uint_fixed_16_16_t fp; intermediate_val = (uint64_t) val.val * mul.val; intermediate_val = intermediate_val >> 16; - WARN_ON(intermediate_val >> 32); - fp.val = clamp_t(uint32_t, intermediate_val, 0, ~0); - return fp; + return clamp_u64_to_fixed16(intermediate_val); } -static inline uint_fixed_16_16_t fixed_16_16_div(uint32_t val, uint32_t d) +static inline uint_fixed_16_16_t div_fixed16(uint32_t val, uint32_t d) { - uint_fixed_16_16_t fp, res; - - fp = u32_to_fixed_16_16(val); - res.val = DIV_ROUND_UP(fp.val, d); - return res; -} - -static inline uint_fixed_16_16_t fixed_16_16_div_u64(uint32_t val, uint32_t d) -{ - uint_fixed_16_16_t res; uint64_t interm_val; interm_val = (uint64_t)val << 16; interm_val = DIV_ROUND_UP_ULL(interm_val, d); - WARN_ON(interm_val >> 32); - res.val = (uint32_t) interm_val; - - return res; + return clamp_u64_to_fixed16(interm_val); } static inline uint32_t div_round_up_u32_fixed16(uint32_t val, @@ -225,16 +215,32 @@ static inline uint32_t div_round_up_u32_fixed16(uint32_t val, return clamp_t(uint32_t, interm_val, 0, ~0); } -static inline uint_fixed_16_16_t mul_u32_fixed_16_16(uint32_t val, +static inline uint_fixed_16_16_t mul_u32_fixed16(uint32_t val, uint_fixed_16_16_t mul) { uint64_t intermediate_val; - uint_fixed_16_16_t fp; intermediate_val = (uint64_t) val * mul.val; - WARN_ON(intermediate_val >> 32); - fp.val = (uint32_t) intermediate_val; - return fp; + return clamp_u64_to_fixed16(intermediate_val); +} + +static inline uint_fixed_16_16_t add_fixed16(uint_fixed_16_16_t add1, + uint_fixed_16_16_t add2) +{ + uint64_t interm_sum; + + interm_sum = (uint64_t) add1.val + add2.val; + return clamp_u64_to_fixed16(interm_sum); +} + +static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1, + uint32_t add2) +{ + uint64_t interm_sum; + uint_fixed_16_16_t interm_add2 = u32_to_fixed16(add2); + + interm_sum = (uint64_t) add1.val + interm_add2.val; + return clamp_u64_to_fixed16(interm_sum); } static inline const char *yesno(bool v) @@ -584,8 +590,7 @@ struct drm_i915_file_private { struct idr context_idr; struct intel_rps_client { - struct list_head link; - unsigned boosts; + atomic_t boosts; } rps; unsigned int bsd_engine; @@ -753,6 +758,7 @@ struct intel_csr { func(has_csr); \ func(has_ddi); \ func(has_dp_mst); \ + func(has_reset_engine); \ func(has_fbc); \ func(has_fpga_dbg); \ func(has_full_ppgtt); \ @@ -917,6 +923,7 @@ struct i915_gpu_state { enum intel_engine_hangcheck_action hangcheck_action; struct i915_address_space *vm; int num_requests; + u32 reset_count; /* position of active request inside the ring */ u32 rq_head, rq_post, rq_tail; @@ -1149,8 +1156,8 @@ struct i915_psr { enum intel_pch { PCH_NONE = 0, /* No PCH present */ PCH_IBX, /* Ibexpeak PCH */ - PCH_CPT, /* Cougarpoint PCH */ - PCH_LPT, /* Lynxpoint PCH */ + PCH_CPT, /* Cougarpoint/Pantherpoint PCH */ + PCH_LPT, /* Lynxpoint/Wildcatpoint PCH */ PCH_SPT, /* Sunrisepoint PCH */ PCH_KBP, /* Kabypoint PCH */ PCH_CNP, /* Cannonpoint PCH */ @@ -1166,6 +1173,7 @@ enum intel_sbi_destination { #define QUIRK_INVERT_BRIGHTNESS (1<<2) #define QUIRK_BACKLIGHT_PRESENT (1<<3) #define QUIRK_PIN_SWIZZLED_PAGES (1<<5) +#define QUIRK_INCREASE_T12_DELAY (1<<6) struct intel_fbdev; struct intel_fbc_work; @@ -1301,13 +1309,10 @@ struct intel_gen6_power_mgmt { int last_adj; enum { LOW_POWER, BETWEEN, HIGH_POWER } power; - spinlock_t client_lock; - struct list_head clients; - bool client_boost; - bool enabled; struct delayed_work autoenable_work; - unsigned boosts; + atomic_t num_waiters; + atomic_t boosts; /* manual wa residency calculations */ struct intel_rps_ei ei; @@ -1550,6 +1555,12 @@ struct i915_gpu_error { * inspect the bit and do the reset directly, otherwise the worker * waits for the struct_mutex. * + * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to + * acquire the struct_mutex to reset an engine, we need an explicit + * flag to prevent two concurrent reset attempts in the same engine. + * As the number of engines continues to grow, allocate the flags from + * the most significant bits. + * * #I915_WEDGED - If reset fails and we can no longer use the GPU, * we set the #I915_WEDGED bit. Prior to command submission, e.g. * i915_gem_request_alloc(), this bit is checked and the sequence @@ -1559,6 +1570,10 @@ struct i915_gpu_error { #define I915_RESET_BACKOFF 0 #define I915_RESET_HANDOFF 1 #define I915_WEDGED (BITS_PER_LONG - 1) +#define I915_RESET_ENGINE (I915_WEDGED - I915_NUM_ENGINES) + + /** Number of times an engine has been reset */ + u32 reset_engine_count[I915_NUM_ENGINES]; /** * Waitqueue to signal when a hang is detected. Used to for waiters @@ -2236,13 +2251,6 @@ struct drm_i915_private { DECLARE_HASHTABLE(mm_structs, 7); struct mutex mm_lock; - /* The hw wants to have a stable context identifier for the lifetime - * of the context (for OA, PASID, faults, etc). This is limited - * in execlists to 21 bits. - */ - struct ida context_hw_ida; -#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */ - /* Kernel Modesetting */ struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; @@ -2303,11 +2311,9 @@ struct drm_i915_private { struct drm_i915_gem_object *vlv_pctx; -#ifdef CONFIG_DRM_FBDEV_EMULATION /* list of fbdev register on this device */ struct intel_fbdev *fbdev; struct work_struct fbdev_suspend_work; -#endif struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; @@ -2321,7 +2327,18 @@ struct drm_i915_private { */ struct mutex av_mutex; - struct list_head context_list; + struct { + struct list_head list; + struct llist_head free_list; + struct work_struct free_work; + + /* The hw wants to have a stable context identifier for the + * lifetime of the context (for OA, PASID, faults, etc). + * This is limited in execlists to 21 bits. + */ + struct ida hw_ida; +#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */ + } contexts; u32 fdi_rx_config; @@ -2996,16 +3013,17 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_POOLED_EU(dev_priv) ((dev_priv)->info.has_pooled_eu) -#define INTEL_PCH_DEVICE_ID_MASK 0xff00 -#define INTEL_PCH_DEVICE_ID_MASK_EXT 0xff80 +#define INTEL_PCH_DEVICE_ID_MASK 0xff80 #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 #define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 +#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80 +#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80 #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 -#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA200 +#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280 #define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 #define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 @@ -3020,9 +3038,11 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT) #define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT) #define HAS_PCH_LPT_LP(dev_priv) \ - ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) + ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \ + (dev_priv)->pch_id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) #define HAS_PCH_LPT_H(dev_priv) \ - ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) + ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE || \ + (dev_priv)->pch_id == INTEL_PCH_WPT_DEVICE_ID_TYPE) #define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT) #define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX) #define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP) @@ -3089,6 +3109,8 @@ extern void i915_driver_unload(struct drm_device *dev); extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask); extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv); extern void i915_reset(struct drm_i915_private *dev_priv); +extern int i915_reset_engine(struct intel_engine_cs *engine); +extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv); extern int intel_guc_reset(struct drm_i915_private *dev_priv); extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine); extern void intel_hangcheck_init(struct drm_i915_private *dev_priv); @@ -3461,11 +3483,22 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error) return READ_ONCE(error->reset_count); } +static inline u32 i915_reset_engine_count(struct i915_gpu_error *error, + struct intel_engine_cs *engine) +{ + return READ_ONCE(error->reset_engine_count[engine->id]); +} + +struct drm_i915_gem_request * +i915_gem_reset_prepare_engine(struct intel_engine_cs *engine); int i915_gem_reset_prepare(struct drm_i915_private *dev_priv); void i915_gem_reset(struct drm_i915_private *dev_priv); +void i915_gem_reset_finish_engine(struct intel_engine_cs *engine); void i915_gem_reset_finish(struct drm_i915_private *dev_priv); void i915_gem_set_wedged(struct drm_i915_private *dev_priv); bool i915_gem_unset_wedged(struct drm_i915_private *dev_priv); +void i915_gem_reset_engine(struct intel_engine_cs *engine, + struct drm_i915_gem_request *request); void i915_gem_init_mmio(struct drm_i915_private *i915); int __must_check i915_gem_init(struct drm_i915_private *dev_priv); @@ -3499,7 +3532,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma); int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align); -int i915_gem_open(struct drm_device *dev, struct drm_file *file); +int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file); void i915_gem_release(struct drm_device *dev, struct drm_file *file); int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, @@ -3531,38 +3564,23 @@ void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj, struct sg_table *pages); static inline struct i915_gem_context * -i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id) +__i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id) { - struct i915_gem_context *ctx; - - lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex); - - ctx = idr_find(&file_priv->context_idr, id); - if (!ctx) - return ERR_PTR(-ENOENT); - - return ctx; + return idr_find(&file_priv->context_idr, id); } static inline struct i915_gem_context * -i915_gem_context_get(struct i915_gem_context *ctx) -{ - kref_get(&ctx->ref); - return ctx; -} - -static inline void i915_gem_context_put(struct i915_gem_context *ctx) +i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id) { - lockdep_assert_held(&ctx->i915->drm.struct_mutex); - kref_put(&ctx->ref, i915_gem_context_free); -} + struct i915_gem_context *ctx; -static inline void i915_gem_context_put_unlocked(struct i915_gem_context *ctx) -{ - struct mutex *lock = &ctx->i915->drm.struct_mutex; + rcu_read_lock(); + ctx = __i915_gem_context_lookup_rcu(file_priv, id); + if (ctx && !kref_get_unless_zero(&ctx->ref)) + ctx = NULL; + rcu_read_unlock(); - if (kref_put_mutex(&ctx->ref, i915_gem_context_free, lock)) - mutex_unlock(lock); + return ctx; } static inline struct intel_timeline * |