]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/gpu/drm/i915/i915_drv.h
drm/i915: Move dev_priv->mm.[un]bound_list to its own lock
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / i915 / i915_drv.h
index 2e1498cae89388a99323336f9a6743fca7692d73..4704cfe93279cffb4d3aea84b12bc4c1518c0c99 100644 (file)
@@ -80,8 +80,8 @@
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20170907"
-#define DRIVER_TIMESTAMP       1504772900
+#define DRIVER_DATE            "20171012"
+#define DRIVER_TIMESTAMP       1507831511
 
 /* 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
@@ -93,7 +93,7 @@
 #define I915_STATE_WARN(condition, format...) ({                       \
        int __ret_warn_on = !!(condition);                              \
        if (unlikely(__ret_warn_on))                                    \
-               if (!WARN(i915.verbose_state_checks, format))           \
+               if (!WARN(i915_modparams.verbose_state_checks, format)) \
                        DRM_ERROR(format);                              \
        unlikely(__ret_warn_on);                                        \
 })
@@ -609,7 +609,7 @@ struct drm_i915_file_private {
 
        struct intel_rps_client {
                atomic_t boosts;
-       } rps;
+       } rps_client;
 
        unsigned int bsd_engine;
 
@@ -725,8 +725,7 @@ struct drm_i915_display_funcs {
                            struct drm_atomic_state *old_state);
        void (*crtc_disable)(struct intel_crtc_state *old_crtc_state,
                             struct drm_atomic_state *old_state);
-       void (*update_crtcs)(struct drm_atomic_state *state,
-                            unsigned int *crtc_vblank_mask);
+       void (*update_crtcs)(struct drm_atomic_state *state);
        void (*audio_codec_enable)(struct drm_connector *connector,
                                   struct intel_encoder *encoder,
                                   const struct drm_display_mode *adjusted_mode);
@@ -777,7 +776,6 @@ struct intel_csr {
        func(has_fpga_dbg); \
        func(has_full_ppgtt); \
        func(has_full_48bit_ppgtt); \
-       func(has_gmbus_irq); \
        func(has_gmch_display); \
        func(has_guc); \
        func(has_guc_ct); \
@@ -785,6 +783,7 @@ struct intel_csr {
        func(has_l3_dpf); \
        func(has_llc); \
        func(has_logical_ring_contexts); \
+       func(has_logical_ring_preemption); \
        func(has_overlay); \
        func(has_pipe_cxsr); \
        func(has_pooled_eu); \
@@ -853,21 +852,30 @@ enum intel_platform {
 };
 
 struct intel_device_info {
-       u32 display_mmio_offset;
        u16 device_id;
-       u8 num_pipes;
-       u8 num_sprites[I915_MAX_PIPES];
-       u8 num_scalers[I915_MAX_PIPES];
-       u8 gen;
        u16 gen_mask;
-       enum intel_platform platform;
+
+       u8 gen;
        u8 gt; /* GT number, 0 if undefined */
-       u8 ring_mask; /* Rings supported by the HW */
        u8 num_rings;
+       u8 ring_mask; /* Rings supported by the HW */
+
+       enum intel_platform platform;
+       u32 platform_mask;
+
+       u32 display_mmio_offset;
+
+       u8 num_pipes;
+       u8 num_sprites[I915_MAX_PIPES];
+       u8 num_scalers[I915_MAX_PIPES];
+
+       unsigned int page_sizes; /* page sizes supported by the HW */
+
 #define DEFINE_FLAG(name) u8 name:1
        DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
 #undef DEFINE_FLAG
        u16 ddb_size; /* in blocks */
+
        /* Register offsets for the various display pipes and transcoders */
        int pipe_offsets[I915_MAX_TRANSCODERS];
        int trans_offsets[I915_MAX_TRANSCODERS];
@@ -976,6 +984,7 @@ struct i915_gpu_state {
                        pid_t pid;
                        u32 handle;
                        u32 hw_id;
+                       int priority;
                        int ban_score;
                        int active;
                        int guilty;
@@ -998,11 +1007,13 @@ struct i915_gpu_state {
                        long jiffies;
                        pid_t pid;
                        u32 context;
+                       int priority;
                        int ban_score;
                        u32 seqno;
                        u32 head;
                        u32 tail;
-               } *requests, execlist[2];
+               } *requests, execlist[EXECLIST_MAX_PORTS];
+               unsigned int num_ports;
 
                struct drm_i915_error_waiter {
                        char comm[TASK_COMM_LEN];
@@ -1306,7 +1317,7 @@ struct intel_rps_ei {
        u32 media_c0;
 };
 
-struct intel_gen6_power_mgmt {
+struct intel_rps {
        /*
         * work, interrupts_enabled and pm_iir are protected by
         * dev_priv->irq_lock
@@ -1347,20 +1358,26 @@ struct intel_gen6_power_mgmt {
        enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
 
        bool enabled;
-       struct delayed_work autoenable_work;
        atomic_t num_waiters;
        atomic_t boosts;
 
        /* manual wa residency calculations */
        struct intel_rps_ei ei;
+};
 
-       /*
-        * Protects RPS/RC6 register access and PCU communication.
-        * Must be taken after struct_mutex if nested. Note that
-        * this lock may be held for long periods of time when
-        * talking to hw - so only take it when talking to hw!
-        */
-       struct mutex hw_lock;
+struct intel_rc6 {
+       bool enabled;
+};
+
+struct intel_llc_pstate {
+       bool enabled;
+};
+
+struct intel_gen6_power_mgmt {
+       struct intel_rps rps;
+       struct intel_rc6 rc6;
+       struct intel_llc_pstate llc_pstate;
+       struct delayed_work autoenable_work;
 };
 
 /* defined intel_pm.c */
@@ -1473,6 +1490,9 @@ struct i915_gem_mm {
         * always the inner lock when overlapping with struct_mutex. */
        struct mutex stolen_lock;
 
+       /* Protects bound_list/unbound_list and #drm_i915_gem_object.mm.link */
+       spinlock_t obj_lock;
+
        /** List of all objects in gtt_space. Used to restore gtt
         * mappings on resume */
        struct list_head bound_list;
@@ -1502,6 +1522,11 @@ struct i915_gem_mm {
        /** Usable portion of the GTT for GEM */
        dma_addr_t stolen_base; /* limited to low memory (32-bit) */
 
+       /**
+        * tmpfs instance used for shmem backed objects
+        */
+       struct vfsmount *gemfs;
+
        /** PPGTT used for aliasing the PPGTT with the GTT */
        struct i915_hw_ppgtt *aliasing_ppgtt;
 
@@ -2245,8 +2270,11 @@ struct drm_i915_private {
        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];
+       /* Context used internally to idle the GPU and setup initial state */
+       struct i915_gem_context *kernel_context;
+       /* Context only to be used for injecting preemption commands */
+       struct i915_gem_context *preempt_context;
        struct i915_vma *semaphore;
 
        struct drm_dma_handle *status_page_dmah;
@@ -2355,6 +2383,8 @@ struct drm_i915_private {
        DECLARE_HASHTABLE(mm_structs, 7);
        struct mutex mm_lock;
 
+       struct intel_ppat ppat;
+
        /* Kernel Modesetting */
 
        struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
@@ -2400,8 +2430,16 @@ struct drm_i915_private {
        /* Cannot be determined by PCIID. You must always read a register. */
        u32 edram_cap;
 
-       /* gen6+ rps state */
-       struct intel_gen6_power_mgmt rps;
+       /*
+        * Protects RPS/RC6 register access and PCU communication.
+        * Must be taken after struct_mutex if nested. Note that
+        * this lock may be held for long periods of time when
+        * talking to hw - so only take it when talking to hw!
+        */
+       struct mutex pcu_lock;
+
+       /* gen6+ GT PM state */
+       struct intel_gen6_power_mgmt gt_pm;
 
        /* ilk-only ips/rps state. Everything in here is protected by the global
         * mchdev_lock in intel_pm.c */
@@ -2512,7 +2550,7 @@ struct drm_i915_private {
                bool distrust_bios_wm;
        } wm;
 
-       struct i915_runtime_pm pm;
+       struct i915_runtime_pm runtime_pm;
 
        struct {
                bool initialized;
@@ -2851,6 +2889,21 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg)
             (((__iter).curr += PAGE_SIZE) >= (__iter).max) ?           \
             (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0)
 
+static inline unsigned int i915_sg_page_sizes(struct scatterlist *sg)
+{
+       unsigned int page_sizes;
+
+       page_sizes = 0;
+       while (sg) {
+               GEM_BUG_ON(sg->offset);
+               GEM_BUG_ON(!IS_ALIGNED(sg->length, PAGE_SIZE));
+               page_sizes |= sg->length;
+               sg = __sg_next(sg);
+       }
+
+       return page_sizes;
+}
+
 static inline unsigned int i915_sg_segment_size(void)
 {
        unsigned int size = swiotlb_max_segment();
@@ -2905,37 +2958,39 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define IS_REVID(p, since, until) \
        (INTEL_REVID(p) >= (since) && INTEL_REVID(p) <= (until))
 
-#define IS_I830(dev_priv)      ((dev_priv)->info.platform == INTEL_I830)
-#define IS_I845G(dev_priv)     ((dev_priv)->info.platform == INTEL_I845G)
-#define IS_I85X(dev_priv)      ((dev_priv)->info.platform == INTEL_I85X)
-#define IS_I865G(dev_priv)     ((dev_priv)->info.platform == INTEL_I865G)
-#define IS_I915G(dev_priv)     ((dev_priv)->info.platform == INTEL_I915G)
-#define IS_I915GM(dev_priv)    ((dev_priv)->info.platform == INTEL_I915GM)
-#define IS_I945G(dev_priv)     ((dev_priv)->info.platform == INTEL_I945G)
-#define IS_I945GM(dev_priv)    ((dev_priv)->info.platform == INTEL_I945GM)
-#define IS_I965G(dev_priv)     ((dev_priv)->info.platform == INTEL_I965G)
-#define IS_I965GM(dev_priv)    ((dev_priv)->info.platform == INTEL_I965GM)
-#define IS_G45(dev_priv)       ((dev_priv)->info.platform == INTEL_G45)
-#define IS_GM45(dev_priv)      ((dev_priv)->info.platform == INTEL_GM45)
+#define IS_PLATFORM(dev_priv, p) ((dev_priv)->info.platform_mask & BIT(p))
+
+#define IS_I830(dev_priv)      IS_PLATFORM(dev_priv, INTEL_I830)
+#define IS_I845G(dev_priv)     IS_PLATFORM(dev_priv, INTEL_I845G)
+#define IS_I85X(dev_priv)      IS_PLATFORM(dev_priv, INTEL_I85X)
+#define IS_I865G(dev_priv)     IS_PLATFORM(dev_priv, INTEL_I865G)
+#define IS_I915G(dev_priv)     IS_PLATFORM(dev_priv, INTEL_I915G)
+#define IS_I915GM(dev_priv)    IS_PLATFORM(dev_priv, INTEL_I915GM)
+#define IS_I945G(dev_priv)     IS_PLATFORM(dev_priv, INTEL_I945G)
+#define IS_I945GM(dev_priv)    IS_PLATFORM(dev_priv, INTEL_I945GM)
+#define IS_I965G(dev_priv)     IS_PLATFORM(dev_priv, INTEL_I965G)
+#define IS_I965GM(dev_priv)    IS_PLATFORM(dev_priv, INTEL_I965GM)
+#define IS_G45(dev_priv)       IS_PLATFORM(dev_priv, INTEL_G45)
+#define IS_GM45(dev_priv)      IS_PLATFORM(dev_priv, INTEL_GM45)
 #define IS_G4X(dev_priv)       (IS_G45(dev_priv) || IS_GM45(dev_priv))
 #define IS_PINEVIEW_G(dev_priv)        (INTEL_DEVID(dev_priv) == 0xa001)
 #define IS_PINEVIEW_M(dev_priv)        (INTEL_DEVID(dev_priv) == 0xa011)
-#define IS_PINEVIEW(dev_priv)  ((dev_priv)->info.platform == INTEL_PINEVIEW)
-#define IS_G33(dev_priv)       ((dev_priv)->info.platform == INTEL_G33)
+#define IS_PINEVIEW(dev_priv)  IS_PLATFORM(dev_priv, INTEL_PINEVIEW)
+#define IS_G33(dev_priv)       IS_PLATFORM(dev_priv, INTEL_G33)
 #define IS_IRONLAKE_M(dev_priv)        (INTEL_DEVID(dev_priv) == 0x0046)
-#define IS_IVYBRIDGE(dev_priv) ((dev_priv)->info.platform == INTEL_IVYBRIDGE)
+#define IS_IVYBRIDGE(dev_priv) IS_PLATFORM(dev_priv, INTEL_IVYBRIDGE)
 #define IS_IVB_GT1(dev_priv)   (IS_IVYBRIDGE(dev_priv) && \
                                 (dev_priv)->info.gt == 1)
-#define IS_VALLEYVIEW(dev_priv)        ((dev_priv)->info.platform == INTEL_VALLEYVIEW)
-#define IS_CHERRYVIEW(dev_priv)        ((dev_priv)->info.platform == INTEL_CHERRYVIEW)
-#define IS_HASWELL(dev_priv)   ((dev_priv)->info.platform == INTEL_HASWELL)
-#define IS_BROADWELL(dev_priv) ((dev_priv)->info.platform == INTEL_BROADWELL)
-#define IS_SKYLAKE(dev_priv)   ((dev_priv)->info.platform == INTEL_SKYLAKE)
-#define IS_BROXTON(dev_priv)   ((dev_priv)->info.platform == INTEL_BROXTON)
-#define IS_KABYLAKE(dev_priv)  ((dev_priv)->info.platform == INTEL_KABYLAKE)
-#define IS_GEMINILAKE(dev_priv)        ((dev_priv)->info.platform == INTEL_GEMINILAKE)
-#define IS_COFFEELAKE(dev_priv)        ((dev_priv)->info.platform == INTEL_COFFEELAKE)
-#define IS_CANNONLAKE(dev_priv)        ((dev_priv)->info.platform == INTEL_CANNONLAKE)
+#define IS_VALLEYVIEW(dev_priv)        IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW)
+#define IS_CHERRYVIEW(dev_priv)        IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)
+#define IS_HASWELL(dev_priv)   IS_PLATFORM(dev_priv, INTEL_HASWELL)
+#define IS_BROADWELL(dev_priv) IS_PLATFORM(dev_priv, INTEL_BROADWELL)
+#define IS_SKYLAKE(dev_priv)   IS_PLATFORM(dev_priv, INTEL_SKYLAKE)
+#define IS_BROXTON(dev_priv)   IS_PLATFORM(dev_priv, INTEL_BROXTON)
+#define IS_KABYLAKE(dev_priv)  IS_PLATFORM(dev_priv, INTEL_KABYLAKE)
+#define IS_GEMINILAKE(dev_priv)        IS_PLATFORM(dev_priv, INTEL_GEMINILAKE)
+#define IS_COFFEELAKE(dev_priv)        IS_PLATFORM(dev_priv, INTEL_COFFEELAKE)
+#define IS_CANNONLAKE(dev_priv)        IS_PLATFORM(dev_priv, INTEL_CANNONLAKE)
 #define IS_MOBILE(dev_priv)    ((dev_priv)->info.is_mobile)
 #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \
                                    (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00)
@@ -2983,6 +3038,8 @@ intel_info(const struct drm_i915_private *dev_priv)
                                 (dev_priv)->info.gt == 3)
 #define IS_CFL_ULT(dev_priv)   (IS_COFFEELAKE(dev_priv) && \
                                 (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0)
+#define IS_CFL_GT2(dev_priv)   (IS_COFFEELAKE(dev_priv) && \
+                                (dev_priv)->info.gt == 2)
 
 #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support)
 
@@ -3023,6 +3080,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 
 #define CNL_REVID_A0           0x0
 #define CNL_REVID_B0           0x1
+#define CNL_REVID_C0           0x2
 
 #define IS_CNL_REVID(p, since, until) \
        (IS_CANNONLAKE(p) && IS_REVID(p, since, until))
@@ -3073,9 +3131,13 @@ intel_info(const struct drm_i915_private *dev_priv)
 
 #define HAS_LOGICAL_RING_CONTEXTS(dev_priv) \
                ((dev_priv)->info.has_logical_ring_contexts)
-#define USES_PPGTT(dev_priv)           (i915.enable_ppgtt)
-#define USES_FULL_PPGTT(dev_priv)      (i915.enable_ppgtt >= 2)
-#define USES_FULL_48BIT_PPGTT(dev_priv)        (i915.enable_ppgtt == 3)
+#define USES_PPGTT(dev_priv)           (i915_modparams.enable_ppgtt)
+#define USES_FULL_PPGTT(dev_priv)      (i915_modparams.enable_ppgtt >= 2)
+#define USES_FULL_48BIT_PPGTT(dev_priv)        (i915_modparams.enable_ppgtt == 3)
+#define HAS_PAGE_SIZES(dev_priv, sizes) ({ \
+       GEM_BUG_ON((sizes) == 0); \
+       ((sizes) & ~(dev_priv)->info.page_sizes) == 0; \
+})
 
 #define HAS_OVERLAY(dev_priv)           ((dev_priv)->info.has_overlay)
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
@@ -3093,9 +3155,12 @@ intel_info(const struct drm_i915_private *dev_priv)
  * even when in MSI mode. This results in spurious interrupt warnings if the
  * legacy irq no. is shared with another device. The kernel then disables that
  * interrupt source and so prevents the other device from working properly.
+ *
+ * Since we don't enable MSI anymore on gen4, we can always use GMBUS/AUX
+ * interrupts.
  */
-#define HAS_AUX_IRQ(dev_priv)   ((dev_priv)->info.gen >= 5)
-#define HAS_GMBUS_IRQ(dev_priv) ((dev_priv)->info.has_gmbus_irq)
+#define HAS_AUX_IRQ(dev_priv)   true
+#define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4)
 
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
  * rows, which changed the alignment requirements and fence programming.
@@ -3273,7 +3338,7 @@ static inline void i915_queue_hangcheck(struct drm_i915_private *dev_priv)
 {
        unsigned long delay;
 
-       if (unlikely(!i915.enable_hangcheck))
+       if (unlikely(!i915_modparams.enable_hangcheck))
                return;
 
        /* Don't continually defer the hangcheck so that it is always run at
@@ -3306,6 +3371,8 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
        return dev_priv->vgpu.active;
 }
 
+u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
+                             enum pipe pipe);
 void
 i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
                     u32 status_mask);
@@ -3487,7 +3554,8 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj,
                                unsigned long n);
 
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
-                                struct sg_table *pages);
+                                struct sg_table *pages,
+                                unsigned int sg_page_sizes);
 int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
 
 static inline int __must_check
@@ -3501,10 +3569,16 @@ i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
        return __i915_gem_object_get_pages(obj);
 }
 
+static inline bool
+i915_gem_object_has_pages(struct drm_i915_gem_object *obj)
+{
+       return !IS_ERR_OR_NULL(READ_ONCE(obj->mm.pages));
+}
+
 static inline void
 __i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
 {
-       GEM_BUG_ON(!obj->mm.pages);
+       GEM_BUG_ON(!i915_gem_object_has_pages(obj));
 
        atomic_inc(&obj->mm.pages_pin_count);
 }
@@ -3518,8 +3592,8 @@ i915_gem_object_has_pinned_pages(struct drm_i915_gem_object *obj)
 static inline void
 __i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
 {
+       GEM_BUG_ON(!i915_gem_object_has_pages(obj));
        GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
-       GEM_BUG_ON(!obj->mm.pages);
 
        atomic_dec(&obj->mm.pages_pin_count);
 }
@@ -3709,8 +3783,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
 }
 
 /* i915_gem_fence_reg.c */
-int __must_check i915_vma_get_fence(struct i915_vma *vma);
-int __must_check i915_vma_put_fence(struct i915_vma *vma);
 struct drm_i915_fence_reg *
 i915_reserve_fence(struct drm_i915_private *dev_priv);
 void i915_unreserve_fence(struct drm_i915_fence_reg *fence);
@@ -3811,6 +3883,7 @@ i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
 /* i915_gem_shrinker.c */
 unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv,
                              unsigned long target,
+                             unsigned long *nr_scanned,
                              unsigned flags);
 #define I915_SHRINK_PURGEABLE 0x1
 #define I915_SHRINK_UNBOUND 0x2