drm/i915: trace down all the register write and read
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / i915_drv.h
index 2af8e1604b44f0ecd784981339c5ab3f0d40aa7f..220ce53d4a9c47f3a2f12ac223aa5e595922d562 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "i915_reg.h"
 #include "intel_bios.h"
+#include "i915_trace.h"
 #include "intel_ringbuffer.h"
 #include <linux/io-mapping.h>
 #include <linux/i2c.h>
@@ -148,6 +149,17 @@ struct drm_i915_error_state {
        u32 ipehr;
        u32 instdone;
        u32 acthd;
+       u32 error; /* gen6+ */
+       u32 bcs_acthd; /* gen6+ blt engine */
+       u32 bcs_ipehr;
+       u32 bcs_ipeir;
+       u32 bcs_instdone;
+       u32 bcs_seqno;
+       u32 vcs_acthd; /* gen6+ bsd engine */
+       u32 vcs_ipehr;
+       u32 vcs_ipeir;
+       u32 vcs_instdone;
+       u32 vcs_seqno;
        u32 instpm;
        u32 instps;
        u32 instdone1;
@@ -171,6 +183,7 @@ struct drm_i915_error_state {
                u32 tiling:2;
                u32 dirty:1;
                u32 purgeable:1;
+               u32 ring:4;
        } *active_bo;
        u32 active_bo_count;
        struct intel_overlay_error_state *overlay;
@@ -275,9 +288,6 @@ typedef struct drm_i915_private {
        int front_offset;
        int current_page;
        int page_flipping;
-#define I915_DEBUG_READ (1<<0)
-#define I915_DEBUG_WRITE (1<<1)
-       unsigned long debug_flags;
 
        wait_queue_head_t irq_queue;
        atomic_t irq_received;
@@ -535,18 +545,13 @@ typedef struct drm_i915_private {
                struct drm_mm vram;
                /** Memory allocator for GTT */
                struct drm_mm gtt_space;
+               /** End of mappable part of GTT */
+               unsigned long gtt_mappable_end;
 
                struct io_mapping *gtt_mapping;
                int gtt_mtrr;
 
-               /**
-                * Membership on list of all loaded devices, used to evict
-                * inactive buffers under memory pressure.
-                *
-                * Modifications should only be done whilst holding the
-                * shrink_list_lock spinlock.
-                */
-               struct list_head shrink_list;
+               struct shrinker inactive_shrinker;
 
                /**
                 * List of objects currently involved in rendering.
@@ -635,15 +640,17 @@ typedef struct drm_i915_private {
                /* storage for physical objects */
                struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
 
-               uint32_t flush_rings;
-
                /* accounting, useful for userland debugging */
                size_t object_memory;
                size_t pin_memory;
                size_t gtt_memory;
+               size_t gtt_mappable_memory;
+               size_t mappable_gtt_used;
+               size_t mappable_gtt_total;
                size_t gtt_total;
                u32 object_count;
                u32 pin_count;
+               u32 gtt_mappable_count;
                u32 gtt_count;
        } mm;
        struct sdvo_device_mapping sdvo_mappings[2];
@@ -747,15 +754,6 @@ struct drm_i915_gem_object {
         */
        unsigned int madv : 2;
 
-       /**
-        * Refcount for the pages array. With the current locking scheme, there
-        * are at most two concurrent users: Binding a bo to the gtt and
-        * pwrite/pread using physical addresses. So two bits for a maximum
-        * of two users are enough.
-        */
-       unsigned int pages_refcount : 2;
-#define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3
-
        /**
         * Current tiling mode for the object.
         */
@@ -773,6 +771,20 @@ struct drm_i915_gem_object {
        unsigned int pin_count : 4;
 #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
 
+       /**
+        * Is the object at the current location in the gtt mappable and
+        * fenceable? Used to avoid costly recalculations.
+        */
+       unsigned int map_and_fenceable : 1;
+
+       /**
+        * Whether the current gtt mapping needs to be mappable (and isn't just
+        * mappable by accident). Track pin and fault separate for a more
+        * accurate mappable working set.
+        */
+       unsigned int fault_mappable : 1;
+       unsigned int pin_mappable : 1;
+
        /** AGP memory structure for our GTT binding. */
        DRM_AGP_MEM *agp_mem;
 
@@ -788,11 +800,6 @@ struct drm_i915_gem_object {
        /* Which ring is refering to is this object */
        struct intel_ring_buffer *ring;
 
-       /**
-        * Fake offset for use by mmap(2)
-        */
-       uint64_t mmap_offset;
-
        /** Breadcrumb of last rendering to the buffer. */
        uint32_t last_rendering_seqno;
 
@@ -1010,7 +1017,8 @@ int i915_gem_init_object(struct drm_gem_object *obj);
 struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,
                                              size_t size);
 void i915_gem_free_object(struct drm_gem_object *obj);
-int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
+                       bool map_and_fenceable);
 void i915_gem_object_unpin(struct drm_gem_object *obj);
 int i915_gem_object_unbind(struct drm_gem_object *obj);
 void i915_gem_release_mmap(struct drm_gem_object *obj);
@@ -1038,13 +1046,13 @@ int i915_gem_object_set_domain(struct drm_gem_object *obj,
 int i915_gem_init_ringbuffer(struct drm_device *dev);
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
-                    unsigned long end);
+                    unsigned long mappable_end, unsigned long end);
 int i915_gpu_idle(struct drm_device *dev);
 int i915_gem_idle(struct drm_device *dev);
-uint32_t i915_add_request(struct drm_device *dev,
-                         struct drm_file *file_priv,
-                         struct drm_i915_gem_request *request,
-                         struct intel_ring_buffer *ring);
+int i915_add_request(struct drm_device *dev,
+                    struct drm_file *file_priv,
+                    struct drm_i915_gem_request *request,
+                    struct intel_ring_buffer *ring);
 int i915_do_wait_request(struct drm_device *dev,
                         uint32_t seqno,
                         bool interruptible,
@@ -1063,22 +1071,16 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
 void i915_gem_free_all_phys_object(struct drm_device *dev);
 void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
 
-void i915_gem_shrinker_init(void);
-void i915_gem_shrinker_exit(void);
-
 /* i915_gem_evict.c */
-int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment);
-int i915_gem_evict_everything(struct drm_device *dev);
-int i915_gem_evict_inactive(struct drm_device *dev);
+int i915_gem_evict_something(struct drm_device *dev, int min_size,
+                            unsigned alignment, bool mappable);
+int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only);
+int i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only);
 
 /* i915_gem_tiling.c */
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
 void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj);
 void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj);
-bool i915_tiling_ok(struct drm_device *dev, int stride, int size,
-                   int tiling_mode);
-bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj,
-                                    int tiling_mode);
 
 /* i915_gem_debug.c */
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
@@ -1172,40 +1174,61 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove
                LOCK_TEST_WITH_RETURN(dev, file_priv);                  \
 } while (0)
 
-static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg)
+static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg, int len)
 {
-       u32 val;
-
-       val = readl(dev_priv->regs + reg);
-       if (dev_priv->debug_flags & I915_DEBUG_READ)
-               printk(KERN_ERR "read 0x%08x from 0x%08x\n", val, reg);
-       return val;
+       u64 val = 0;
+
+       switch (len) {
+       case 8:
+               val = readq(dev_priv->regs + reg);
+               break;
+       case 4:
+               val = readl(dev_priv->regs + reg);
+               break;
+       case 2:
+               val = readw(dev_priv->regs + reg);
+               break;
+       case 1:
+               val = readb(dev_priv->regs + reg);
+               break;
+       }
+       trace_i915_reg_rw('R', reg, val, len);
+
+       return val;
 }
 
-static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
-                             u32 val)
+static inline void
+i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len)
 {
-       writel(val, dev_priv->regs + reg);
-       if (dev_priv->debug_flags & I915_DEBUG_WRITE)
-               printk(KERN_ERR "wrote 0x%08x to 0x%08x\n", val, reg);
+       /* Trace down the write operation before the real write */
+       trace_i915_reg_rw('W', reg, val, len);
+       switch (len) {
+       case 8:
+               writeq(val, dev_priv->regs + reg);
+               break;
+       case 4:
+               writel(val, dev_priv->regs + reg);
+               break;
+       case 2:
+               writew(val, dev_priv->regs + reg);
+               break;
+       case 1:
+               writeb(val, dev_priv->regs + reg);
+               break;
+       }
 }
 
-#define I915_READ(reg)          i915_read(dev_priv, (reg))
-#define I915_WRITE(reg, val)    i915_write(dev_priv, (reg), (val))
-#define I915_READ16(reg)       readw(dev_priv->regs + (reg))
-#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg))
-#define I915_READ8(reg)                readb(dev_priv->regs + (reg))
-#define I915_WRITE8(reg, val)  writeb(val, dev_priv->regs + (reg))
-#define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg))
-#define I915_READ64(reg)       readq(dev_priv->regs + (reg))
+#define I915_READ(reg)         i915_read(dev_priv, (reg), 4)
+#define I915_WRITE(reg, val)   i915_write(dev_priv, (reg), (val), 4)
+#define I915_READ16(reg)       i915_read(dev_priv, (reg), 2)
+#define I915_WRITE16(reg, val) i915_write(dev_priv, (reg), (val), 2)
+#define I915_READ8(reg)                i915_read(dev_priv, (reg), 1)
+#define I915_WRITE8(reg, val)  i915_write(dev_priv, (reg), (val), 1)
+#define I915_WRITE64(reg, val) i915_write(dev_priv, (reg), (val), 8)
+#define I915_READ64(reg)       i915_read(dev_priv, (reg), 8)
 #define POSTING_READ(reg)      (void)I915_READ(reg)
 #define POSTING_READ16(reg)    (void)I915_READ16(reg)
 
-#define I915_DEBUG_ENABLE_IO() (dev_priv->debug_flags |= I915_DEBUG_READ | \
-                               I915_DEBUG_WRITE)
-#define I915_DEBUG_DISABLE_IO() (dev_priv->debug_flags &= ~(I915_DEBUG_READ | \
-                                                           I915_DEBUG_WRITE))
-
 #define BEGIN_LP_RING(n) \
        intel_ring_begin(&dev_priv->render_ring, (n))
 
@@ -1295,6 +1318,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
 
 #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
 #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
+#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)