Merge tag 'drm-intel-next-2021-08-10-1' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / i915_drv.h
index 6ac90cc..005b1ce 100644 (file)
@@ -202,6 +202,68 @@ struct drm_i915_file_private {
                struct rcu_head rcu;
        };
 
+       /** @proto_context_lock: Guards all struct i915_gem_proto_context
+        * operations
+        *
+        * This not only guards @proto_context_xa, but is always held
+        * whenever we manipulate any struct i915_gem_proto_context,
+        * including finalizing it on first actual use of the GEM context.
+        *
+        * See i915_gem_proto_context.
+        */
+       struct mutex proto_context_lock;
+
+       /** @proto_context_xa: xarray of struct i915_gem_proto_context
+        *
+        * Historically, the context uAPI allowed for two methods of
+        * setting context parameters: SET_CONTEXT_PARAM and
+        * CONTEXT_CREATE_EXT_SETPARAM.  The former is allowed to be called
+        * at any time while the later happens as part of
+        * GEM_CONTEXT_CREATE.  Everything settable via one was settable
+        * via the other.  While some params are fairly simple and setting
+        * them on a live context is harmless such as the context priority,
+        * others are far trickier such as the VM or the set of engines.
+        * In order to swap out the VM, for instance, we have to delay
+        * until all current in-flight work is complete, swap in the new
+        * VM, and then continue.  This leads to a plethora of potential
+        * race conditions we'd really rather avoid.
+        *
+        * We have since disallowed setting these more complex parameters
+        * on active contexts.  This works by delaying the creation of the
+        * actual context until after the client is done configuring it
+        * with SET_CONTEXT_PARAM.  From the perspective of the client, it
+        * has the same u32 context ID the whole time.  From the
+        * perspective of i915, however, it's a struct i915_gem_proto_context
+        * right up until the point where we attempt to do something which
+        * the proto-context can't handle.  Then the struct i915_gem_context
+        * gets created.
+        *
+        * This is accomplished via a little xarray dance.  When
+        * GEM_CONTEXT_CREATE is called, we create a struct
+        * i915_gem_proto_context, reserve a slot in @context_xa but leave
+        * it NULL, and place the proto-context in the corresponding slot
+        * in @proto_context_xa.  Then, in i915_gem_context_lookup(), we
+        * first check @context_xa.  If it's there, we return the struct
+        * i915_gem_context and we're done.  If it's not, we look in
+        * @proto_context_xa and, if we find it there, we create the actual
+        * context and kill the proto-context.
+        *
+        * In order for this dance to work properly, everything which ever
+        * touches a struct i915_gem_proto_context is guarded by
+        * @proto_context_lock, including context creation.  Yes, this
+        * means context creation now takes a giant global lock but it
+        * can't really be helped and that should never be on any driver's
+        * fast-path anyway.
+        */
+       struct xarray proto_context_xa;
+
+       /** @context_xa: xarray of fully created i915_gem_context
+        *
+        * Write access to this xarray is guarded by @proto_context_lock.
+        * Otherwise, writers may race with finalize_create_context_locked().
+        *
+        * See @proto_context_xa.
+        */
        struct xarray context_xa;
        struct xarray vm_xa;
 
@@ -332,15 +394,6 @@ struct drm_i915_display_funcs {
        void (*read_luts)(struct intel_crtc_state *crtc_state);
 };
 
-enum i915_cache_level {
-       I915_CACHE_NONE = 0,
-       I915_CACHE_LLC, /* also used for snoopable memory on non-LLC */
-       I915_CACHE_L3_LLC, /* gen7+, L3 sits between the domain specifc
-                             caches, eg sampler/render caches, and the
-                             large Last-Level-Cache. LLC is coherent with
-                             the CPU, but L3 is only visible to the GPU. */
-       I915_CACHE_WT, /* hsw:gt3e WriteThrough for scanouts */
-};
 
 #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */
 
@@ -556,7 +609,7 @@ struct i915_gem_mm {
         * notifier_lock for mmu notifiers, memory may not be allocated
         * while holding this lock.
         */
-       spinlock_t notifier_lock;
+       rwlock_t notifier_lock;
 #endif
 
        /* shrinker accounting, also useful for userland debugging */
@@ -1145,6 +1198,8 @@ struct drm_i915_private {
        /* For i915gm/i945gm vblank irq workaround */
        u8 vblank_enabled;
 
+       bool irq_enabled;
+
        /* perform PHY state sanity checks? */
        bool chv_phy_assert[2];
 
@@ -1250,8 +1305,6 @@ static inline struct drm_i915_private *pdev_to_i915(struct pci_dev *pdev)
 
 #define IP_VER(ver, rel)               ((ver) << 8 | (rel))
 
-#define IP_VER(ver, rel)               ((ver) << 8 | (rel))
-
 #define GRAPHICS_VER(i915)             (INTEL_INFO(i915)->graphics_ver)
 #define GRAPHICS_VER_FULL(i915)                IP_VER(INTEL_INFO(i915)->graphics_ver, \
                                               INTEL_INFO(i915)->graphics_rel)
@@ -1281,7 +1334,7 @@ static inline struct drm_i915_private *pdev_to_i915(struct pci_dev *pdev)
 
 #define IS_GT_STEP(__i915, since, until) \
        (drm_WARN_ON(&(__i915)->drm, INTEL_GT_STEP(__i915) == STEP_NONE), \
-        INTEL_GT_STEP(__i915) >= (since) && INTEL_GT_STEP(__i915) <= (until))
+        INTEL_GT_STEP(__i915) >= (since) && INTEL_GT_STEP(__i915) < (until))
 
 static __always_inline unsigned int
 __platform_mask_index(const struct intel_runtime_info *info,
@@ -1503,8 +1556,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
        (IS_ALDERLAKE_P(__i915) && \
         IS_GT_STEP(__i915, since, until))
 
-#define IS_XEHPSDV_GT_STEP(p, since, until) \
-       (IS_XEHPSDV(p) && IS_GT_STEP(__i915, since, until))
+#define IS_XEHPSDV_GT_STEP(__i915, since, until) \
+       (IS_XEHPSDV(__i915) && IS_GT_STEP(__i915, since, until))
 
 /*
  * DG2 hardware steppings are a bit unusual.  The hardware design was forked
@@ -1635,6 +1688,9 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
 #define HAS_64BIT_RELOC(dev_priv) (INTEL_INFO(dev_priv)->has_64bit_reloc)
 
+#define HAS_MSLICES(dev_priv) \
+       (INTEL_INFO(dev_priv)->has_mslices)
+
 #define HAS_IPC(dev_priv)               (INTEL_INFO(dev_priv)->display.has_ipc)
 
 #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
@@ -1724,9 +1780,6 @@ void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
 void i915_gem_init_early(struct drm_i915_private *dev_priv);
 void i915_gem_cleanup_early(struct drm_i915_private *dev_priv);
 
-struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915,
-                                                u16 type, u16 instance);
-
 static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 {
        /*
@@ -1823,24 +1876,18 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
 
 struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags);
 
-static inline struct i915_gem_context *
-__i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
+static inline struct i915_address_space *
+i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id)
 {
-       return xa_load(&file_priv->context_xa, id);
-}
-
-static inline struct i915_gem_context *
-i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
-{
-       struct i915_gem_context *ctx;
+       struct i915_address_space *vm;
 
        rcu_read_lock();
-       ctx = __i915_gem_context_lookup_rcu(file_priv, id);
-       if (ctx && !kref_get_unless_zero(&ctx->ref))
-               ctx = NULL;
+       vm = xa_load(&file_priv->vm_xa, id);
+       if (vm && !kref_get_unless_zero(&vm->ref))
+               vm = NULL;
        rcu_read_unlock();
 
-       return ctx;
+       return vm;
 }
 
 /* i915_gem_evict.c */
@@ -1879,17 +1926,12 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
 int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
 int intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
 void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
-unsigned long *intel_engine_cmd_parser_alloc_jump_whitelist(u32 batch_length,
-                                                           bool trampoline);
-
 int intel_engine_cmd_parser(struct intel_engine_cs *engine,
                            struct i915_vma *batch,
                            unsigned long batch_offset,
                            unsigned long batch_length,
                            struct i915_vma *shadow,
-                           unsigned long *jump_whitelist,
-                           void *shadow_map,
-                           const void *batch_map);
+                           bool trampoline);
 #define I915_CMD_PARSER_TRAMPOLINE_SIZE 8
 
 /* intel_device_info.c */
@@ -1912,8 +1954,8 @@ int remap_io_sg(struct vm_area_struct *vma,
 
 static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
 {
-       if (GRAPHICS_VER(i915) >= 10)
-               return CNL_HWS_CSB_WRITE_INDEX;
+       if (GRAPHICS_VER(i915) >= 11)
+               return ICL_HWS_CSB_WRITE_INDEX;
        else
                return I915_HWS_CSB_WRITE_INDEX;
 }