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 6d49a9f5c2b1ea2cc5ff8c3ce31ceda802b27d03..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;
@@ -206,7 +219,6 @@ struct intel_device_info {
        u8 is_pineview : 1;
        u8 is_broadwater : 1;
        u8 is_crestline : 1;
-       u8 is_ironlake : 1;
        u8 has_fbc : 1;
        u8 has_rc6 : 1;
        u8 has_pipe_cxsr : 1;
@@ -216,6 +228,7 @@ struct intel_device_info {
        u8 overlay_needs_physical : 1;
        u8 supports_tv : 1;
        u8 has_bsd_ring : 1;
+       u8 has_blt_ring : 1;
 };
 
 enum no_fbc_reason {
@@ -255,6 +268,7 @@ typedef struct drm_i915_private {
        struct pci_dev *bridge_dev;
        struct intel_ring_buffer render_ring;
        struct intel_ring_buffer bsd_ring;
+       struct intel_ring_buffer blt_ring;
        uint32_t next_seqno;
 
        drm_dma_handle_t *status_page_dmah;
@@ -274,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;
@@ -350,6 +361,7 @@ typedef struct drm_i915_private {
                int bpp;
                struct edp_power_seq pps;
        } edp;
+       bool no_aux_handshake;
 
        struct notifier_block lid_notifier;
 
@@ -533,18 +545,24 @@ 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;
 
+               struct shrinker inactive_shrinker;
+
                /**
-                * Membership on list of all loaded devices, used to evict
-                * inactive buffers under memory pressure.
+                * List of objects currently involved in rendering.
+                *
+                * Includes buffers having the contents of their GPU caches
+                * flushed, not necessarily primitives.  last_rendering_seqno
+                * represents when the rendering involved will be completed.
                 *
-                * Modifications should only be done whilst holding the
-                * shrink_list_lock spinlock.
+                * A reference is held on the buffer while on this list.
                 */
-               struct list_head shrink_list;
+               struct list_head active_list;
 
                /**
                 * List of objects which are not in the ringbuffer but which
@@ -557,15 +575,6 @@ typedef struct drm_i915_private {
                 */
                struct list_head flushing_list;
 
-               /**
-                * List of objects currently pending a GPU write flush.
-                *
-                * All elements on this list will belong to either the
-                * active_list or flushing_list, last_rendering_seqno can
-                * be used to differentiate between the two elements.
-                */
-               struct list_head gpu_write_list;
-
                /**
                 * LRU list of objects which are not in the ringbuffer and
                 * are ready to unbind, but are still in the GTT.
@@ -604,16 +613,6 @@ typedef struct drm_i915_private {
                 */
                struct delayed_work retire_work;
 
-               /**
-                * Waiting sequence number, if any
-                */
-               uint32_t waiting_gem_seqno;
-
-               /**
-                * Last seq seen at irq time
-                */
-               uint32_t irq_gem_seqno;
-
                /**
                 * Flag if the X Server, and thus DRM, is not currently in
                 * control of the device.
@@ -641,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];
@@ -713,7 +714,8 @@ struct drm_i915_gem_object {
        struct drm_mm_node *gtt_space;
 
        /** This object's place on the active/flushing/inactive lists */
-       struct list_head list;
+       struct list_head ring_list;
+       struct list_head mm_list;
        /** This object's place on GPU write list */
        struct list_head gpu_write_list;
        /** This object's place on eviction list */
@@ -752,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.
         */
@@ -778,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;
 
@@ -793,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;
 
@@ -1015,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);
@@ -1043,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,
@@ -1068,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,
@@ -1177,64 +1174,69 @@ 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 I915_VERBOSE 0
+#define BEGIN_LP_RING(n) \
+       intel_ring_begin(&dev_priv->render_ring, (n))
 
-#define BEGIN_LP_RING(n)  do { \
-       drm_i915_private_t *dev_priv__ = dev->dev_private;                \
-       if (I915_VERBOSE)                                               \
-               DRM_DEBUG("   BEGIN_LP_RING %x\n", (int)(n));           \
-       intel_ring_begin(dev, &dev_priv__->render_ring, (n));           \
-} while (0)
-
-
-#define OUT_RING(x) do {                                               \
-       drm_i915_private_t *dev_priv__ = dev->dev_private;              \
-       if (I915_VERBOSE)                                               \
-               DRM_DEBUG("   OUT_RING %x\n", (int)(x));                \
-       intel_ring_emit(dev, &dev_priv__->render_ring, x);              \
-} while (0)
+#define OUT_RING(x) \
+       intel_ring_emit(&dev_priv->render_ring, x)
 
-#define ADVANCE_LP_RING() do {                                         \
-       drm_i915_private_t *dev_priv__ = dev->dev_private;                \
-       if (I915_VERBOSE)                                               \
-               DRM_DEBUG("ADVANCE_LP_RING %x\n",                       \
-                               dev_priv__->render_ring.tail);          \
-       intel_ring_advance(dev, &dev_priv__->render_ring);              \
-} while(0)
+#define ADVANCE_LP_RING() \
+       intel_ring_advance(&dev_priv->render_ring)
 
 /**
  * Reads a dword out of the status page, which is written to from the command
@@ -1277,7 +1279,6 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
 #define IS_G33(dev)            (INTEL_INFO(dev)->is_g33)
 #define IS_IRONLAKE_D(dev)     ((dev)->pci_device == 0x0042)
 #define IS_IRONLAKE_M(dev)     ((dev)->pci_device == 0x0046)
-#define IS_IRONLAKE(dev)       (INTEL_INFO(dev)->is_ironlake)
 #define IS_MOBILE(dev)         (INTEL_INFO(dev)->is_mobile)
 
 #define IS_GEN2(dev)   (INTEL_INFO(dev)->gen == 2)
@@ -1287,6 +1288,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
 #define IS_GEN6(dev)   (INTEL_INFO(dev)->gen == 6)
 
 #define HAS_BSD(dev)            (INTEL_INFO(dev)->has_bsd_ring)
+#define HAS_BLT(dev)            (INTEL_INFO(dev)->has_blt_ring)
 #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
 
 #define HAS_OVERLAY(dev)               (INTEL_INFO(dev)->has_overlay)
@@ -1298,8 +1300,8 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
 #define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \
                                                      IS_I915GM(dev)))
 #define SUPPORTS_DIGITAL_OUTPUTS(dev)  (!IS_GEN2(dev) && !IS_PINEVIEW(dev))
-#define SUPPORTS_INTEGRATED_HDMI(dev)  (IS_G4X(dev) || IS_IRONLAKE(dev))
-#define SUPPORTS_INTEGRATED_DP(dev)    (IS_G4X(dev) || IS_IRONLAKE(dev))
+#define SUPPORTS_INTEGRATED_HDMI(dev)  (IS_G4X(dev) || IS_GEN5(dev))
+#define SUPPORTS_INTEGRATED_DP(dev)    (IS_G4X(dev) || IS_GEN5(dev))
 #define SUPPORTS_EDP(dev)              (IS_IRONLAKE_M(dev))
 #define SUPPORTS_TV(dev)               (INTEL_INFO(dev)->supports_tv)
 #define I915_HAS_HOTPLUG(dev)           (INTEL_INFO(dev)->has_hotplug)
@@ -1311,12 +1313,12 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
 #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
 #define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6)
 
-#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||        \
-                           IS_GEN6(dev))
-#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
+#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev))
+#define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev))
 
 #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)