drm/i915: Add convenience wrappers for vma's object get/put
[cascardo/linux.git] / drivers / gpu / drm / i915 / i915_drv.h
index 21f9390..3285c8e 100644 (file)
@@ -61,6 +61,7 @@
 #include "i915_gem.h"
 #include "i915_gem_gtt.h"
 #include "i915_gem_render_state.h"
+#include "i915_gem_request.h"
 
 #include "intel_gvt.h"
 
@@ -69,7 +70,7 @@
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20160711"
+#define DRIVER_DATE            "20160808"
 
 #undef WARN_ON
 /* Many gcc seem to no see through this and fall over :( */
@@ -401,7 +402,7 @@ struct drm_i915_file_private {
                unsigned boosts;
        } rps;
 
-       unsigned int bsd_ring;
+       unsigned int bsd_engine;
 };
 
 /* Used by dp and fdi links */
@@ -431,8 +432,6 @@ void intel_link_compute_m_n(int bpp, int nlanes,
 #define DRIVER_MINOR           6
 #define DRIVER_PATCHLEVEL      0
 
-#define WATCH_LISTS    0
-
 struct opregion_header;
 struct opregion_acpi;
 struct opregion_swsci;
@@ -476,130 +475,6 @@ struct sdvo_device_mapping {
        u8 ddc_pin;
 };
 
-struct intel_display_error_state;
-
-struct drm_i915_error_state {
-       struct kref ref;
-       struct timeval time;
-
-       char error_msg[128];
-       bool simulated;
-       int iommu;
-       u32 reset_count;
-       u32 suspend_count;
-
-       /* Generic register state */
-       u32 eir;
-       u32 pgtbl_er;
-       u32 ier;
-       u32 gtier[4];
-       u32 ccid;
-       u32 derrmr;
-       u32 forcewake;
-       u32 error; /* gen6+ */
-       u32 err_int; /* gen7 */
-       u32 fault_data0; /* gen8, gen9 */
-       u32 fault_data1; /* gen8, gen9 */
-       u32 done_reg;
-       u32 gac_eco;
-       u32 gam_ecochk;
-       u32 gab_ctl;
-       u32 gfx_mode;
-       u32 extra_instdone[I915_NUM_INSTDONE_REG];
-       u64 fence[I915_MAX_NUM_FENCES];
-       struct intel_overlay_error_state *overlay;
-       struct intel_display_error_state *display;
-       struct drm_i915_error_object *semaphore_obj;
-
-       struct drm_i915_error_ring {
-               bool valid;
-               /* Software tracked state */
-               bool waiting;
-               int num_waiters;
-               int hangcheck_score;
-               enum intel_ring_hangcheck_action hangcheck_action;
-               int num_requests;
-
-               /* our own tracking of ring head and tail */
-               u32 cpu_ring_head;
-               u32 cpu_ring_tail;
-
-               u32 last_seqno;
-               u32 semaphore_seqno[I915_NUM_ENGINES - 1];
-
-               /* Register state */
-               u32 start;
-               u32 tail;
-               u32 head;
-               u32 ctl;
-               u32 hws;
-               u32 ipeir;
-               u32 ipehr;
-               u32 instdone;
-               u32 bbstate;
-               u32 instpm;
-               u32 instps;
-               u32 seqno;
-               u64 bbaddr;
-               u64 acthd;
-               u32 fault_reg;
-               u64 faddr;
-               u32 rc_psmi; /* sleep state */
-               u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
-
-               struct drm_i915_error_object {
-                       int page_count;
-                       u64 gtt_offset;
-                       u32 *pages[0];
-               } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
-
-               struct drm_i915_error_object *wa_ctx;
-
-               struct drm_i915_error_request {
-                       long jiffies;
-                       u32 seqno;
-                       u32 tail;
-               } *requests;
-
-               struct drm_i915_error_waiter {
-                       char comm[TASK_COMM_LEN];
-                       pid_t pid;
-                       u32 seqno;
-               } *waiters;
-
-               struct {
-                       u32 gfx_mode;
-                       union {
-                               u64 pdp[4];
-                               u32 pp_dir_base;
-                       };
-               } vm_info;
-
-               pid_t pid;
-               char comm[TASK_COMM_LEN];
-       } ring[I915_NUM_ENGINES];
-
-       struct drm_i915_error_buffer {
-               u32 size;
-               u32 name;
-               u32 rseqno[I915_NUM_ENGINES], wseqno;
-               u64 gtt_offset;
-               u32 read_domains;
-               u32 write_domain;
-               s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
-               s32 pinned:2;
-               u32 tiling:2;
-               u32 dirty:1;
-               u32 purgeable:1;
-               u32 userptr:1;
-               s32 ring:4;
-               u32 cache_level:3;
-       } **active_bo, **pinned_bo;
-
-       u32 *active_bo_count, *pinned_bo_count;
-       u32 vm_count;
-};
-
 struct intel_connector;
 struct intel_encoder;
 struct intel_crtc_state;
@@ -794,6 +669,7 @@ struct intel_device_info {
        u8 gen;
        u16 gen_mask;
        u8 ring_mask; /* Rings supported by the HW */
+       u8 num_rings;
        DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
        /* Register offsets for the various display pipes and transcoders */
        int pipe_offsets[I915_MAX_TRANSCODERS];
@@ -823,6 +699,131 @@ struct intel_device_info {
 #undef DEFINE_FLAG
 #undef SEP_SEMICOLON
 
+struct intel_display_error_state;
+
+struct drm_i915_error_state {
+       struct kref ref;
+       struct timeval time;
+
+       char error_msg[128];
+       bool simulated;
+       int iommu;
+       u32 reset_count;
+       u32 suspend_count;
+       struct intel_device_info device_info;
+
+       /* Generic register state */
+       u32 eir;
+       u32 pgtbl_er;
+       u32 ier;
+       u32 gtier[4];
+       u32 ccid;
+       u32 derrmr;
+       u32 forcewake;
+       u32 error; /* gen6+ */
+       u32 err_int; /* gen7 */
+       u32 fault_data0; /* gen8, gen9 */
+       u32 fault_data1; /* gen8, gen9 */
+       u32 done_reg;
+       u32 gac_eco;
+       u32 gam_ecochk;
+       u32 gab_ctl;
+       u32 gfx_mode;
+       u32 extra_instdone[I915_NUM_INSTDONE_REG];
+       u64 fence[I915_MAX_NUM_FENCES];
+       struct intel_overlay_error_state *overlay;
+       struct intel_display_error_state *display;
+       struct drm_i915_error_object *semaphore_obj;
+
+       struct drm_i915_error_engine {
+               int engine_id;
+               /* Software tracked state */
+               bool waiting;
+               int num_waiters;
+               int hangcheck_score;
+               enum intel_engine_hangcheck_action hangcheck_action;
+               struct i915_address_space *vm;
+               int num_requests;
+
+               /* our own tracking of ring head and tail */
+               u32 cpu_ring_head;
+               u32 cpu_ring_tail;
+
+               u32 last_seqno;
+               u32 semaphore_seqno[I915_NUM_ENGINES - 1];
+
+               /* Register state */
+               u32 start;
+               u32 tail;
+               u32 head;
+               u32 ctl;
+               u32 hws;
+               u32 ipeir;
+               u32 ipehr;
+               u32 instdone;
+               u32 bbstate;
+               u32 instpm;
+               u32 instps;
+               u32 seqno;
+               u64 bbaddr;
+               u64 acthd;
+               u32 fault_reg;
+               u64 faddr;
+               u32 rc_psmi; /* sleep state */
+               u32 semaphore_mboxes[I915_NUM_ENGINES - 1];
+
+               struct drm_i915_error_object {
+                       int page_count;
+                       u64 gtt_offset;
+                       u32 *pages[0];
+               } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
+
+               struct drm_i915_error_object *wa_ctx;
+
+               struct drm_i915_error_request {
+                       long jiffies;
+                       u32 seqno;
+                       u32 head;
+                       u32 tail;
+               } *requests;
+
+               struct drm_i915_error_waiter {
+                       char comm[TASK_COMM_LEN];
+                       pid_t pid;
+                       u32 seqno;
+               } *waiters;
+
+               struct {
+                       u32 gfx_mode;
+                       union {
+                               u64 pdp[4];
+                               u32 pp_dir_base;
+                       };
+               } vm_info;
+
+               pid_t pid;
+               char comm[TASK_COMM_LEN];
+       } engine[I915_NUM_ENGINES];
+
+       struct drm_i915_error_buffer {
+               u32 size;
+               u32 name;
+               u32 rseqno[I915_NUM_ENGINES], wseqno;
+               u64 gtt_offset;
+               u32 read_domains;
+               u32 write_domain;
+               s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
+               u32 tiling:2;
+               u32 dirty:1;
+               u32 purgeable:1;
+               u32 userptr:1;
+               s32 engine:4;
+               u32 cache_level:3;
+       } *active_bo[I915_NUM_ENGINES], *pinned_bo;
+       u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
+       struct i915_address_space *active_vm[I915_NUM_ENGINES];
+};
+
 enum i915_cache_level {
        I915_CACHE_NONE = 0,
        I915_CACHE_LLC, /* also used for snoopable memory on non-LLC */
@@ -893,7 +894,7 @@ struct i915_gem_context {
 
        struct intel_context {
                struct drm_i915_gem_object *state;
-               struct intel_ringbuffer *ringbuf;
+               struct intel_ring *ring;
                struct i915_vma *lrc_vma;
                uint32_t *lrc_reg_state;
                u64 lrc_desc;
@@ -908,6 +909,7 @@ struct i915_gem_context {
        struct list_head link;
 
        u8 remap_slice;
+       bool closed:1;
 };
 
 enum fb_op_origin {
@@ -1061,13 +1063,6 @@ struct intel_gmbus {
 
 struct i915_suspend_saved_registers {
        u32 saveDSPARB;
-       u32 saveLVDS;
-       u32 savePP_ON_DELAYS;
-       u32 savePP_OFF_DELAYS;
-       u32 savePP_ON;
-       u32 savePP_OFF;
-       u32 savePP_CONTROL;
-       u32 savePP_DIVISOR;
        u32 saveFBC_CONTROL;
        u32 saveCACHE_MODE_0;
        u32 saveMI_ARB_STATE;
@@ -1173,6 +1168,7 @@ struct intel_gen6_power_mgmt {
        u8 max_freq_softlimit;  /* Max frequency permitted by the driver */
        u8 max_freq;            /* Maximum frequency, RP0 if not overclocking */
        u8 min_freq;            /* AKA RPn. Minimum frequency */
+       u8 boost_freq;          /* Frequency to request when wait boosting */
        u8 idle_freq;           /* Frequency to request when we are idle */
        u8 efficient_freq;      /* AKA RPe. Pre-determined balanced frequency */
        u8 rp1_freq;            /* "less than" RP0 power/freqency */
@@ -1190,11 +1186,9 @@ struct intel_gen6_power_mgmt {
        bool client_boost;
 
        bool enabled;
-       struct delayed_work delayed_resume_work;
+       struct delayed_work autoenable_work;
        unsigned boosts;
 
-       struct intel_rps_client semaphores, mmioflips;
-
        /* manual wa residency calculations */
        struct intel_rps_ei up_ei, down_ei;
 
@@ -1319,7 +1313,6 @@ struct i915_gem_mm {
        struct notifier_block oom_notifier;
        struct notifier_block vmap_notifier;
        struct shrinker shrinker;
-       bool shrinker_no_lock_stealing;
 
        /** LRU list of objects with fence regs on them. */
        struct list_head fence_list;
@@ -1331,7 +1324,7 @@ struct i915_gem_mm {
        bool interruptible;
 
        /* the indicator for dispatch video commands on two BSD rings */
-       unsigned int bsd_ring_dispatch_index;
+       unsigned int bsd_engine_dispatch_index;
 
        /** Bit 6 swizzling required for X tiling */
        uint32_t bit_6_swizzle_x;
@@ -1670,7 +1663,7 @@ struct intel_pipe_crc {
 };
 
 struct i915_frontbuffer_tracking {
-       struct mutex lock;
+       spinlock_t lock;
 
        /*
         * Tracking bits for delayed frontbuffer flushing du to gpu activity or
@@ -1705,18 +1698,6 @@ struct i915_virtual_gpu {
        bool active;
 };
 
-struct i915_execbuffer_params {
-       struct drm_device               *dev;
-       struct drm_file                 *file;
-       uint32_t                        dispatch_flags;
-       uint32_t                        args_batch_start_offset;
-       uint64_t                        batch_obj_vm_offset;
-       struct intel_engine_cs *engine;
-       struct drm_i915_gem_object      *batch_obj;
-       struct i915_gem_context            *ctx;
-       struct drm_i915_gem_request     *request;
-};
-
 /* used in computing the new watermarks state */
 struct intel_wm_config {
        unsigned int num_pipes_active;
@@ -1763,13 +1744,15 @@ struct drm_i915_private {
 
        uint32_t psr_mmio_base;
 
+       uint32_t pps_mmio_base;
+
        wait_queue_head_t gmbus_wait_queue;
 
        struct pci_dev *bridge_dev;
        struct i915_gem_context *kernel_context;
        struct intel_engine_cs engine[I915_NUM_ENGINES];
        struct drm_i915_gem_object *semaphore_obj;
-       uint32_t last_seqno, next_seqno;
+       u32 next_seqno;
 
        struct drm_dma_handle *status_page_dmah;
        struct resource mch_res;
@@ -1854,6 +1837,7 @@ struct drm_i915_private {
        enum modeset_restore modeset_restore;
        struct mutex modeset_restore_lock;
        struct drm_atomic_state *modeset_restore_state;
+       struct drm_modeset_acquire_ctx reset_ctx;
 
        struct list_head vm_list; /* Global list of all address spaces */
        struct i915_ggtt ggtt; /* VM representing the global address space */
@@ -2016,12 +2000,7 @@ struct drm_i915_private {
 
        /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
        struct {
-               int (*execbuf_submit)(struct i915_execbuffer_params *params,
-                                     struct drm_i915_gem_execbuffer2 *args,
-                                     struct list_head *vmas);
-               int (*init_engines)(struct drm_device *dev);
                void (*cleanup_engine)(struct intel_engine_cs *engine);
-               void (*stop_engine)(struct intel_engine_cs *engine);
 
                /**
                 * Is the GPU currently considered idle, or busy executing
@@ -2144,8 +2123,6 @@ struct drm_i915_gem_object_ops {
  */
 #define INTEL_MAX_SPRITE_BITS_PER_PIPE 5
 #define INTEL_FRONTBUFFER_BITS_PER_PIPE 8
-#define INTEL_FRONTBUFFER_BITS \
-       (INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES)
 #define INTEL_FRONTBUFFER_PRIMARY(pipe) \
        (1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
 #define INTEL_FRONTBUFFER_CURSOR(pipe) \
@@ -2169,18 +2146,21 @@ struct drm_i915_gem_object {
        struct drm_mm_node *stolen;
        struct list_head global_list;
 
-       struct list_head engine_list[I915_NUM_ENGINES];
        /** Used in execbuf to temporarily hold a ref */
        struct list_head obj_exec_link;
 
        struct list_head batch_pool_link;
 
+       unsigned long flags;
        /**
         * This is set if the object is on the active lists (has pending
         * rendering and so a non-zero seqno), and is not set if it i s on
         * inactive (ready to be unbound) list.
         */
-       unsigned int active:I915_NUM_ENGINES;
+#define I915_BO_ACTIVE_SHIFT 0
+#define I915_BO_ACTIVE_MASK ((1 << I915_NUM_ENGINES) - 1)
+#define __I915_BO_ACTIVE(bo) \
+       ((READ_ONCE((bo)->flags) >> I915_BO_ACTIVE_SHIFT) & I915_BO_ACTIVE_MASK)
 
        /**
         * This is set if the object has been written to since last bound
@@ -2200,10 +2180,6 @@ struct drm_i915_gem_object {
         */
        unsigned int madv:2;
 
-       /**
-        * Current tiling mode for the object.
-        */
-       unsigned int tiling_mode:2;
        /**
         * Whether the tiling parameters for the currently associated fence
         * register have changed. Note that for the purposes of tracking
@@ -2234,9 +2210,17 @@ struct drm_i915_gem_object {
        unsigned int cache_level:3;
        unsigned int cache_dirty:1;
 
-       unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS;
+       atomic_t frontbuffer_bits;
+
+       /** Current tiling stride for the object, if it's tiled. */
+       unsigned int tiling_and_stride;
+#define FENCE_MINIMUM_STRIDE 128 /* See i915_tiling_ok() */
+#define TILING_MASK (FENCE_MINIMUM_STRIDE-1)
+#define STRIDE_MASK (~TILING_MASK)
 
        unsigned int has_wc_mmap;
+       /** Count of VMA actually bound by this object */
+       unsigned int bind_count;
        unsigned int pin_display;
 
        struct sg_table *pages;
@@ -2256,14 +2240,10 @@ struct drm_i915_gem_object {
         * requests on one ring where the write request is older than the
         * read request. This allows for the CPU to read from an active
         * buffer by only waiting for the write to complete.
-        * */
-       struct drm_i915_gem_request *last_read_req[I915_NUM_ENGINES];
-       struct drm_i915_gem_request *last_write_req;
-       /** Breadcrumb of last fenced GPU access to the buffer. */
-       struct drm_i915_gem_request *last_fenced_req;
-
-       /** Current tiling stride for the object, if it's tiled. */
-       uint32_t stride;
+        */
+       struct i915_gem_active last_read[I915_NUM_ENGINES];
+       struct i915_gem_active last_write;
+       struct i915_gem_active last_fence;
 
        /** References from framebuffers, locks out tiling changes. */
        unsigned long framebuffer_references;
@@ -2287,7 +2267,56 @@ struct drm_i915_gem_object {
                } userptr;
        };
 };
-#define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
+
+static inline struct drm_i915_gem_object *
+to_intel_bo(struct drm_gem_object *gem)
+{
+       /* Assert that to_intel_bo(NULL) == NULL */
+       BUILD_BUG_ON(offsetof(struct drm_i915_gem_object, base));
+
+       return container_of(gem, struct drm_i915_gem_object, base);
+}
+
+static inline struct drm_i915_gem_object *
+i915_gem_object_lookup(struct drm_file *file, u32 handle)
+{
+       return to_intel_bo(drm_gem_object_lookup(file, handle));
+}
+
+__deprecated
+extern struct drm_gem_object *
+drm_gem_object_lookup(struct drm_file *file, u32 handle);
+
+__attribute__((nonnull))
+static inline struct drm_i915_gem_object *
+i915_gem_object_get(struct drm_i915_gem_object *obj)
+{
+       drm_gem_object_reference(&obj->base);
+       return obj;
+}
+
+__deprecated
+extern void drm_gem_object_reference(struct drm_gem_object *);
+
+__attribute__((nonnull))
+static inline void
+i915_gem_object_put(struct drm_i915_gem_object *obj)
+{
+       drm_gem_object_unreference(&obj->base);
+}
+
+__deprecated
+extern void drm_gem_object_unreference(struct drm_gem_object *);
+
+__attribute__((nonnull))
+static inline void
+i915_gem_object_put_unlocked(struct drm_i915_gem_object *obj)
+{
+       drm_gem_object_unreference_unlocked(&obj->base);
+}
+
+__deprecated
+extern void drm_gem_object_unreference_unlocked(struct drm_gem_object *);
 
 static inline bool
 i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
@@ -2295,6 +2324,67 @@ i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
        return obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE;
 }
 
+static inline unsigned long
+i915_gem_object_get_active(const struct drm_i915_gem_object *obj)
+{
+       return (obj->flags >> I915_BO_ACTIVE_SHIFT) & I915_BO_ACTIVE_MASK;
+}
+
+static inline bool
+i915_gem_object_is_active(const struct drm_i915_gem_object *obj)
+{
+       return i915_gem_object_get_active(obj);
+}
+
+static inline void
+i915_gem_object_set_active(struct drm_i915_gem_object *obj, int engine)
+{
+       obj->flags |= BIT(engine + I915_BO_ACTIVE_SHIFT);
+}
+
+static inline void
+i915_gem_object_clear_active(struct drm_i915_gem_object *obj, int engine)
+{
+       obj->flags &= ~BIT(engine + I915_BO_ACTIVE_SHIFT);
+}
+
+static inline bool
+i915_gem_object_has_active_engine(const struct drm_i915_gem_object *obj,
+                                 int engine)
+{
+       return obj->flags & BIT(engine + I915_BO_ACTIVE_SHIFT);
+}
+
+static inline unsigned int
+i915_gem_object_get_tiling(struct drm_i915_gem_object *obj)
+{
+       return obj->tiling_and_stride & TILING_MASK;
+}
+
+static inline bool
+i915_gem_object_is_tiled(struct drm_i915_gem_object *obj)
+{
+       return i915_gem_object_get_tiling(obj) != I915_TILING_NONE;
+}
+
+static inline unsigned int
+i915_gem_object_get_stride(struct drm_i915_gem_object *obj)
+{
+       return obj->tiling_and_stride & STRIDE_MASK;
+}
+
+static inline struct i915_vma *i915_vma_get(struct i915_vma *vma)
+{
+       i915_gem_object_get(vma->obj);
+       return vma;
+}
+
+static inline void i915_vma_put(struct i915_vma *vma)
+{
+       lockdep_assert_held(&vma->vm->dev->struct_mutex);
+       i915_gem_object_put(vma->obj);
+}
+
 /*
  * Optimised SGL iterator for GEM objects
  */
@@ -2365,171 +2455,6 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg)
             (((__iter).curr += PAGE_SIZE) < (__iter).max) ||           \
             ((__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0))
 
-/**
- * Request queue structure.
- *
- * The request queue allows us to note sequence numbers that have been emitted
- * and may be associated with active buffers to be retired.
- *
- * By keeping this list, we can avoid having to do questionable sequence
- * number comparisons on buffer last_read|write_seqno. It also allows an
- * emission time to be associated with the request for tracking how far ahead
- * of the GPU the submission is.
- *
- * The requests are reference counted, so upon creation they should have an
- * initial reference taken using kref_init
- */
-struct drm_i915_gem_request {
-       struct kref ref;
-
-       /** On Which ring this request was generated */
-       struct drm_i915_private *i915;
-       struct intel_engine_cs *engine;
-       struct intel_signal_node signaling;
-
-        /** GEM sequence number associated with the previous request,
-         * when the HWS breadcrumb is equal to this the GPU is processing
-         * this request.
-         */
-       u32 previous_seqno;
-
-        /** GEM sequence number associated with this request,
-         * when the HWS breadcrumb is equal or greater than this the GPU
-         * has finished processing this request.
-         */
-       u32 seqno;
-
-       /** Position in the ringbuffer of the start of the request */
-       u32 head;
-
-       /**
-        * Position in the ringbuffer of the start of the postfix.
-        * This is required to calculate the maximum available ringbuffer
-        * space without overwriting the postfix.
-        */
-        u32 postfix;
-
-       /** Position in the ringbuffer of the end of the whole request */
-       u32 tail;
-
-       /** Preallocate space in the ringbuffer for the emitting the request */
-       u32 reserved_space;
-
-       /**
-        * Context and ring buffer related to this request
-        * Contexts are refcounted, so when this request is associated with a
-        * context, we must increment the context's refcount, to guarantee that
-        * it persists while any request is linked to it. Requests themselves
-        * are also refcounted, so the request will only be freed when the last
-        * reference to it is dismissed, and the code in
-        * i915_gem_request_free() will then decrement the refcount on the
-        * context.
-        */
-       struct i915_gem_context *ctx;
-       struct intel_ringbuffer *ringbuf;
-
-       /**
-        * Context related to the previous request.
-        * As the contexts are accessed by the hardware until the switch is
-        * completed to a new context, the hardware may still be writing
-        * to the context object after the breadcrumb is visible. We must
-        * not unpin/unbind/prune that object whilst still active and so
-        * we keep the previous context pinned until the following (this)
-        * request is retired.
-        */
-       struct i915_gem_context *previous_context;
-
-       /** Batch buffer related to this request if any (used for
-           error state dump only) */
-       struct drm_i915_gem_object *batch_obj;
-
-       /** Time at which this request was emitted, in jiffies. */
-       unsigned long emitted_jiffies;
-
-       /** global list entry for this request */
-       struct list_head list;
-
-       struct drm_i915_file_private *file_priv;
-       /** file_priv list entry for this request */
-       struct list_head client_list;
-
-       /** process identifier submitting this request */
-       struct pid *pid;
-
-       /**
-        * The ELSP only accepts two elements at a time, so we queue
-        * context/tail pairs on a given queue (ring->execlist_queue) until the
-        * hardware is available. The queue serves a double purpose: we also use
-        * it to keep track of the up to 2 contexts currently in the hardware
-        * (usually one in execution and the other queued up by the GPU): We
-        * only remove elements from the head of the queue when the hardware
-        * informs us that an element has been completed.
-        *
-        * All accesses to the queue are mediated by a spinlock
-        * (ring->execlist_lock).
-        */
-
-       /** Execlist link in the submission queue.*/
-       struct list_head execlist_link;
-
-       /** Execlists no. of times this request has been sent to the ELSP */
-       int elsp_submitted;
-
-       /** Execlists context hardware id. */
-       unsigned ctx_hw_id;
-};
-
-struct drm_i915_gem_request * __must_check
-i915_gem_request_alloc(struct intel_engine_cs *engine,
-                      struct i915_gem_context *ctx);
-void i915_gem_request_free(struct kref *req_ref);
-int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
-                                  struct drm_file *file);
-
-static inline uint32_t
-i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
-{
-       return req ? req->seqno : 0;
-}
-
-static inline struct intel_engine_cs *
-i915_gem_request_get_engine(struct drm_i915_gem_request *req)
-{
-       return req ? req->engine : NULL;
-}
-
-static inline struct drm_i915_gem_request *
-i915_gem_request_reference(struct drm_i915_gem_request *req)
-{
-       if (req)
-               kref_get(&req->ref);
-       return req;
-}
-
-static inline void
-i915_gem_request_unreference(struct drm_i915_gem_request *req)
-{
-       kref_put(&req->ref, i915_gem_request_free);
-}
-
-static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
-                                          struct drm_i915_gem_request *src)
-{
-       if (src)
-               i915_gem_request_reference(src);
-
-       if (*pdst)
-               i915_gem_request_unreference(*pdst);
-
-       *pdst = src;
-}
-
-/*
- * XXX: i915_gem_request_completed should be here but currently needs the
- * definition of i915_seqno_passed() which is below. It will be moved in
- * a later patch when the call to i915_seqno_passed() is obsoleted...
- */
-
 /*
  * A command that requires special handling by the command parser.
  */
@@ -2617,8 +2542,9 @@ struct drm_i915_cmd_descriptor {
 /*
  * A table of commands requiring special handling by the command parser.
  *
- * Each ring has an array of tables. Each table consists of an array of command
- * descriptors, which must be sorted with command opcodes in ascending order.
+ * Each engine has an array of tables. Each table consists of an array of
+ * command descriptors, which must be sorted with command opcodes in
+ * ascending order.
  */
 struct drm_i915_cmd_table {
        const struct drm_i915_cmd_descriptor *table;
@@ -2932,6 +2858,8 @@ extern int i915_resume_switcheroo(struct drm_device *dev);
 int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
                                int enable_ppgtt);
 
+bool intel_sanitize_semaphores(struct drm_i915_private *dev_priv, int value);
+
 /* i915_drv.c */
 void __printf(3, 4)
 __i915_printk(struct drm_i915_private *dev_priv, const char *level,
@@ -3107,11 +3035,6 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
                              struct drm_file *file_priv);
 int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
                             struct drm_file *file_priv);
-void i915_gem_execbuffer_move_to_active(struct list_head *vmas,
-                                       struct drm_i915_gem_request *req);
-int i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,
-                                  struct drm_i915_gem_execbuffer2 *args,
-                                  struct list_head *vmas);
 int i915_gem_execbuffer(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 int i915_gem_execbuffer2(struct drm_device *dev, void *data,
@@ -3150,40 +3073,24 @@ struct drm_i915_gem_object *i915_gem_object_create(struct drm_device *dev,
                                                  size_t size);
 struct drm_i915_gem_object *i915_gem_object_create_from_data(
                struct drm_device *dev, const void *data, size_t size);
+void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_free_object(struct drm_gem_object *obj);
-void i915_gem_vma_destroy(struct i915_vma *vma);
-
-/* Flags used by pin/bind&friends. */
-#define PIN_MAPPABLE   (1<<0)
-#define PIN_NONBLOCK   (1<<1)
-#define PIN_GLOBAL     (1<<2)
-#define PIN_OFFSET_BIAS        (1<<3)
-#define PIN_USER       (1<<4)
-#define PIN_UPDATE     (1<<5)
-#define PIN_ZONE_4G    (1<<6)
-#define PIN_HIGH       (1<<7)
-#define PIN_OFFSET_FIXED       (1<<8)
-#define PIN_OFFSET_MASK (~4095)
-int __must_check
-i915_gem_object_pin(struct drm_i915_gem_object *obj,
-                   struct i915_address_space *vm,
-                   uint32_t alignment,
-                   uint64_t flags);
+
 int __must_check
 i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
                         const struct i915_ggtt_view *view,
-                        uint32_t alignment,
-                        uint64_t flags);
+                        u64 size,
+                        u64 alignment,
+                        u64 flags);
 
 int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
                  u32 flags);
 void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
-/*
- * BEWARE: Do not use the function below unless you can _absolutely_
- * _guarantee_ VMA in question is _not in use_ anywhere.
- */
-int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
+void i915_vma_close(struct i915_vma *vma);
+void i915_vma_destroy(struct i915_vma *vma);
+
+int i915_gem_object_unbind(struct drm_i915_gem_object *obj);
 int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
 void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
 void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
@@ -3250,13 +3157,20 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
        obj->pages_pin_count--;
 }
 
+enum i915_map_type {
+       I915_MAP_WB = 0,
+       I915_MAP_WC,
+};
+
 /**
  * i915_gem_object_pin_map - return a contiguous mapping of the entire object
  * @obj - the object to map into kernel address space
+ * @type - the type of mapping, used to select pgprot_t
  *
  * Calls i915_gem_object_pin_pages() to prevent reaping of the object's
  * pages and then returns a contiguous mapping of the backing storage into
- * the kernel address space.
+ * the kernel address space. Based on the @type of mapping, the PTE will be
+ * set to either WriteBack or WriteCombine (via pgprot_t).
  *
  * The caller must hold the struct_mutex, and is responsible for calling
  * i915_gem_object_unpin_map() when the mapping is no longer required.
@@ -3264,7 +3178,8 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
  * Returns the pointer through which to access the mapped object, or an
  * ERR_PTR() on error.
  */
-void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj);
+void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
+                                          enum i915_map_type type);
 
 /**
  * i915_gem_object_unpin_map - releases an earlier mapping
@@ -3285,10 +3200,10 @@ static inline void i915_gem_object_unpin_map(struct drm_i915_gem_object *obj)
 
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
-                        struct intel_engine_cs *to,
-                        struct drm_i915_gem_request **to_req);
+                        struct drm_i915_gem_request *to);
 void i915_vma_move_to_active(struct i915_vma *vma,
-                            struct drm_i915_gem_request *req);
+                            struct drm_i915_gem_request *req,
+                            unsigned int flags);
 int i915_gem_dumb_create(struct drm_file *file_priv,
                         struct drm_device *dev,
                         struct drm_mode_create_dumb *args);
@@ -3299,44 +3214,12 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
                       struct drm_i915_gem_object *new,
                       unsigned frontbuffer_bits);
 
-/**
- * Returns true if seq1 is later than seq2.
- */
-static inline bool
-i915_seqno_passed(uint32_t seq1, uint32_t seq2)
-{
-       return (int32_t)(seq1 - seq2) >= 0;
-}
-
-static inline bool i915_gem_request_started(const struct drm_i915_gem_request *req)
-{
-       return i915_seqno_passed(intel_engine_get_seqno(req->engine),
-                                req->previous_seqno);
-}
-
-static inline bool i915_gem_request_completed(const struct drm_i915_gem_request *req)
-{
-       return i915_seqno_passed(intel_engine_get_seqno(req->engine),
-                                req->seqno);
-}
-
-bool __i915_spin_request(const struct drm_i915_gem_request *request,
-                        int state, unsigned long timeout_us);
-static inline bool i915_spin_request(const struct drm_i915_gem_request *request,
-                                    int state, unsigned long timeout_us)
-{
-       return (i915_gem_request_started(request) &&
-               __i915_spin_request(request, state, timeout_us));
-}
-
-int __must_check i915_gem_get_seqno(struct drm_i915_private *dev_priv, u32 *seqno);
 int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno);
 
 struct drm_i915_gem_request *
 i915_gem_find_active_request(struct intel_engine_cs *engine);
 
 void i915_gem_retire_requests(struct drm_i915_private *dev_priv);
-void i915_gem_retire_requests_ring(struct intel_engine_cs *engine);
 
 static inline u32 i915_reset_counter(struct i915_gpu_error *error)
 {
@@ -3381,24 +3264,13 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
 void i915_gem_reset(struct drm_device *dev);
 bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
 int __must_check i915_gem_init(struct drm_device *dev);
-int i915_gem_init_engines(struct drm_device *dev);
 int __must_check i915_gem_init_hw(struct drm_device *dev);
 void i915_gem_init_swizzling(struct drm_device *dev);
 void i915_gem_cleanup_engines(struct drm_device *dev);
-int __must_check i915_gem_wait_for_idle(struct drm_i915_private *dev_priv);
+int __must_check i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
+                                       bool interruptible);
 int __must_check i915_gem_suspend(struct drm_device *dev);
-void __i915_add_request(struct drm_i915_gem_request *req,
-                       struct drm_i915_gem_object *batch_obj,
-                       bool flush_caches);
-#define i915_add_request(req) \
-       __i915_add_request(req, NULL, true)
-#define i915_add_request_no_flush(req) \
-       __i915_add_request(req, NULL, false)
-int __i915_wait_request(struct drm_i915_gem_request *req,
-                       bool interruptible,
-                       s64 *timeout,
-                       struct intel_rps_client *rps);
-int __must_check i915_wait_request(struct drm_i915_gem_request *req);
+void i915_gem_resume(struct drm_device *dev);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int __must_check
 i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
@@ -3419,11 +3291,10 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
 int i915_gem_open(struct drm_device *dev, struct drm_file *file);
 void i915_gem_release(struct drm_device *dev, struct drm_file *file);
 
-uint32_t
-i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode);
-uint32_t
-i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size,
-                           int tiling_mode, bool fenced);
+u64 i915_gem_get_ggtt_size(struct drm_i915_private *dev_priv, u64 size,
+                          int tiling_mode);
+u64 i915_gem_get_ggtt_alignment(struct drm_i915_private *dev_priv, u64 size,
+                               int tiling_mode, bool fenced);
 
 int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
                                    enum i915_cache_level cache_level);
@@ -3444,7 +3315,6 @@ i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
        return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
 }
 
-bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o);
 bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
                                  const struct i915_ggtt_view *view);
 bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
@@ -3478,7 +3348,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
        return container_of(vm, struct i915_hw_ppgtt, base);
 }
 
-
 static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
 {
        return i915_gem_obj_ggtt_bound_view(obj, &i915_ggtt_view_normal);
@@ -3487,18 +3356,6 @@ static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
 unsigned long
 i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj);
 
-static inline int __must_check
-i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj,
-                     uint32_t alignment,
-                     unsigned flags)
-{
-       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
-       struct i915_ggtt *ggtt = &dev_priv->ggtt;
-
-       return i915_gem_object_pin(obj, &ggtt->base,
-                                  alignment, flags | PIN_GLOBAL);
-}
-
 void i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj,
                                     const struct i915_ggtt_view *view);
 static inline void
@@ -3528,6 +3385,7 @@ void i915_gem_context_reset(struct drm_device *dev);
 int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
 void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 int i915_switch_context(struct drm_i915_gem_request *req);
+int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv);
 void i915_gem_context_free(struct kref *ctx_ref);
 struct drm_i915_gem_object *
 i915_gem_alloc_context_obj(struct drm_device *dev, size_t size);
@@ -3548,12 +3406,14 @@ i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
        return ctx;
 }
 
-static inline void i915_gem_context_reference(struct i915_gem_context *ctx)
+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_unreference(struct i915_gem_context *ctx)
+static inline void i915_gem_context_put(struct i915_gem_context *ctx)
 {
        lockdep_assert_held(&ctx->i915->drm.struct_mutex);
        kref_put(&ctx->ref, i915_gem_context_free);
@@ -3576,13 +3436,10 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
                                       struct drm_file *file);
 
 /* i915_gem_evict.c */
-int __must_check i915_gem_evict_something(struct drm_device *dev,
-                                         struct i915_address_space *vm,
-                                         int min_size,
-                                         unsigned alignment,
+int __must_check i915_gem_evict_something(struct i915_address_space *vm,
+                                         u64 min_size, u64 alignment,
                                          unsigned cache_level,
-                                         unsigned long start,
-                                         unsigned long end,
+                                         u64 start, u64 end,
                                          unsigned flags);
 int __must_check i915_gem_evict_for_vma(struct i915_vma *target);
 int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
@@ -3634,16 +3491,9 @@ static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_objec
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
 
        return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
-               obj->tiling_mode != I915_TILING_NONE;
+               i915_gem_object_is_tiled(obj);
 }
 
-/* i915_gem_debug.c */
-#if WATCH_LISTS
-int i915_verify_lists(struct drm_device *dev);
-#else
-#define i915_verify_lists(dev) 0
-#endif
-
 /* i915_debugfs.c */
 #ifdef CONFIG_DEBUG_FS
 int i915_debugfs_register(struct drm_i915_private *dev_priv);
@@ -3684,15 +3534,15 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
 
 /* i915_cmd_parser.c */
 int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
-int i915_cmd_parser_init_ring(struct intel_engine_cs *engine);
-void i915_cmd_parser_fini_ring(struct intel_engine_cs *engine);
-bool i915_needs_cmd_parser(struct intel_engine_cs *engine);
-int i915_parse_cmds(struct intel_engine_cs *engine,
-                   struct drm_i915_gem_object *batch_obj,
-                   struct drm_i915_gem_object *shadow_batch_obj,
-                   u32 batch_start_offset,
-                   u32 batch_len,
-                   bool is_master);
+int intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
+void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
+bool intel_engine_needs_cmd_parser(struct intel_engine_cs *engine);
+int intel_engine_cmd_parser(struct intel_engine_cs *engine,
+                           struct drm_i915_gem_object *batch_obj,
+                           struct drm_i915_gem_object *shadow_batch_obj,
+                           u32 batch_start_offset,
+                           u32 batch_len,
+                           bool is_master);
 
 /* i915_suspend.c */
 extern int i915_save_state(struct drm_device *dev);
@@ -3800,7 +3650,6 @@ extern void intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
 extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
                                  bool enable);
 
-extern bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv);
 int i915_reg_read_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file);
 
@@ -4017,7 +3866,7 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req)
         * is woken.
         */
        if (engine->irq_seqno_barrier &&
-           READ_ONCE(engine->breadcrumbs.irq_seqno_bh) == current &&
+           rcu_access_pointer(engine->breadcrumbs.irq_seqno_bh) == current &&
            cmpxchg_relaxed(&engine->breadcrumbs.irq_posted, 1, 0)) {
                struct task_struct *tsk;
 
@@ -4042,7 +3891,7 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req)
                 * irq_posted == false but we are still running).
                 */
                rcu_read_lock();
-               tsk = READ_ONCE(engine->breadcrumbs.irq_seqno_bh);
+               tsk = rcu_dereference(engine->breadcrumbs.irq_seqno_bh);
                if (tsk && tsk != current)
                        /* Note that if the bottom-half is changed as we
                         * are sending the wake-up, the new bottom-half will
@@ -4071,4 +3920,22 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req)
        return false;
 }
 
+void i915_memcpy_init_early(struct drm_i915_private *dev_priv);
+bool i915_memcpy_from_wc(void *dst, const void *src, unsigned long len);
+
+#define ptr_unpack_bits(ptr, bits) ({                                  \
+       unsigned long __v = (unsigned long)(ptr);                       \
+       (bits) = __v & ~PAGE_MASK;                                      \
+       (typeof(ptr))(__v & PAGE_MASK);                                 \
+})
+
+#define ptr_pack_bits(ptr, bits)                                       \
+       ((typeof(ptr))((unsigned long)(ptr) | (bits)))
+
+#define fetch_and_zero(ptr) ({                                         \
+       typeof(*ptr) __T = *(ptr);                                      \
+       *(ptr) = (typeof(*ptr))0;                                       \
+       __T;                                                            \
+})
+
 #endif