drm/i915: Don't emit semaphore wait if wrap happened
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / i915_drv.h
index 8c7c43f07873d4f124ce6608adb4f739529ff6bf..9da67824dde302866b0ae98e02e0b3370d95c8e3 100644 (file)
@@ -30,6 +30,8 @@
 #ifndef _I915_DRV_H_
 #define _I915_DRV_H_
 
+#include <uapi/drm/i915_drm.h>
+
 #include "i915_reg.h"
 #include "intel_bios.h"
 #include "intel_ringbuffer.h"
@@ -40,6 +42,7 @@
 #include <linux/backlight.h>
 #include <linux/intel-iommu.h>
 #include <linux/kref.h>
+#include <linux/pm_qos.h>
 
 /* General customization:
  */
@@ -83,7 +86,12 @@ enum port {
 };
 #define port_name(p) ((p) + 'A')
 
-#define I915_GEM_GPU_DOMAINS   (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
+#define I915_GEM_GPU_DOMAINS \
+       (I915_GEM_DOMAIN_RENDER | \
+        I915_GEM_DOMAIN_SAMPLER | \
+        I915_GEM_DOMAIN_COMMAND | \
+        I915_GEM_DOMAIN_INSTRUCTION | \
+        I915_GEM_DOMAIN_VERTEX)
 
 #define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++)
 
@@ -101,6 +109,19 @@ struct intel_pch_pll {
 };
 #define I915_NUM_PLLS 2
 
+/* Used by dp and fdi links */
+struct intel_link_m_n {
+       uint32_t        tu;
+       uint32_t        gmch_m;
+       uint32_t        gmch_n;
+       uint32_t        link_m;
+       uint32_t        link_n;
+};
+
+void intel_link_compute_m_n(int bpp, int nlanes,
+                           int pixel_clock, int link_clock,
+                           struct intel_link_m_n *m_n);
+
 struct intel_ddi_plls {
        int spll_refcount;
        int wrpll1_refcount;
@@ -197,6 +218,7 @@ struct drm_i915_error_state {
        u32 instdone[I915_NUM_RINGS];
        u32 acthd[I915_NUM_RINGS];
        u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1];
+       u32 semaphore_seqno[I915_NUM_RINGS][I915_NUM_RINGS - 1];
        u32 rc_psmi[I915_NUM_RINGS]; /* sleep state */
        /* our own tracking of ring head and tail */
        u32 cpu_ring_head[I915_NUM_RINGS];
@@ -390,7 +412,7 @@ struct intel_fbc_work;
 
 struct intel_gmbus {
        struct i2c_adapter adapter;
-       bool force_bit;
+       u32 force_bit;
        u32 reg0;
        u32 gpio_reg;
        struct i2c_algo_bit_data bit_algo;
@@ -402,7 +424,6 @@ struct i915_suspend_saved_registers {
        u32 saveDSPACNTR;
        u32 saveDSPBCNTR;
        u32 saveDSPARB;
-       u32 saveHWS;
        u32 savePIPEACONF;
        u32 savePIPEBCONF;
        u32 savePIPEASRC;
@@ -562,8 +583,19 @@ struct intel_gen6_power_mgmt {
        u8 cur_delay;
        u8 min_delay;
        u8 max_delay;
+
+       struct delayed_work delayed_resume_work;
+
+       /*
+        * Protects RPS/RC6 register access and PCU communication.
+        * Must be taken after struct_mutex if nested.
+        */
+       struct mutex hw_lock;
 };
 
+/* defined intel_pm.c */
+extern spinlock_t mchdev_lock;
+
 struct intel_ilk_power_mgmt {
        u8 cur_delay;
        u8 min_delay;
@@ -586,8 +618,27 @@ struct intel_ilk_power_mgmt {
        struct drm_i915_gem_object *renderctx;
 };
 
+struct i915_dri1_state {
+       unsigned allow_batchbuffer : 1;
+       u32 __iomem *gfx_hws_cpu_addr;
+
+       unsigned int cpp;
+       int back_offset;
+       int front_offset;
+       int current_page;
+       int page_flipping;
+
+       uint32_t counter;
+};
+
+struct intel_l3_parity {
+       u32 *remap_info;
+       struct work_struct error_work;
+};
+
 typedef struct drm_i915_private {
        struct drm_device *dev;
+       struct kmem_cache *slab;
 
        const struct intel_device_info *info;
 
@@ -602,10 +653,11 @@ typedef struct drm_i915_private {
        /** forcewake_count is protected by gt_lock */
        unsigned forcewake_count;
        /** gt_lock is also taken in irq contexts. */
-       struct spinlock gt_lock;
+       spinlock_t gt_lock;
 
        struct intel_gmbus gmbus[GMBUS_NUM_PORTS];
 
+
        /** gmbus_mutex protects against concurrent usage of the single hw gmbus
         * controller on different i2c buses. */
        struct mutex gmbus_mutex;
@@ -615,12 +667,13 @@ typedef struct drm_i915_private {
         */
        uint32_t gpio_mmio_base;
 
+       wait_queue_head_t gmbus_wait_queue;
+
        struct pci_dev *bridge_dev;
        struct intel_ring_buffer ring[I915_NUM_RINGS];
-       uint32_t next_seqno;
+       uint32_t last_seqno, next_seqno;
 
        drm_dma_handle_t *status_page_dmah;
-       uint32_t counter;
        struct resource mch_res;
 
        atomic_t irq_received;
@@ -628,6 +681,9 @@ typedef struct drm_i915_private {
        /* protects the irq masks */
        spinlock_t irq_lock;
 
+       /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */
+       struct pm_qos_request pm_qos;
+
        /* DPIO indirect register protection */
        spinlock_t dpio_lock;
 
@@ -639,6 +695,7 @@ typedef struct drm_i915_private {
 
        u32 hotplug_supported_mask;
        struct work_struct hotplug_work;
+       bool enable_hotplug_processing;
 
        int num_pipe;
        int num_pch_pll;
@@ -680,7 +737,6 @@ typedef struct drm_i915_private {
        unsigned int display_clock_mode:1;
        int lvds_ssc_freq;
        unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
-       unsigned int lvds_val; /* used for checking LVDS channel mode */
        struct {
                int rate;
                int lanes;
@@ -713,6 +769,7 @@ typedef struct drm_i915_private {
 
        /* PCH chipset type */
        enum intel_pch pch_type;
+       unsigned short pch_id;
 
        unsigned long quirks;
 
@@ -721,7 +778,7 @@ typedef struct drm_i915_private {
 
        struct {
                /** Bridge to intel-gtt-ko */
-               const struct intel_gtt *gtt;
+               struct intel_gtt *gtt;
                /** Memory allocator for GTT stolen memory */
                struct drm_mm stolen;
                /** Memory allocator for GTT */
@@ -740,6 +797,7 @@ typedef struct drm_i915_private {
                unsigned long gtt_start;
                unsigned long gtt_mappable_end;
                unsigned long gtt_end;
+               unsigned long stolen_base; /* limited to low memory (32-bit) */
 
                struct io_mapping *gtt_mapping;
                phys_addr_t gtt_base_addr;
@@ -748,8 +806,6 @@ typedef struct drm_i915_private {
                /** PPGTT used for aliasing the PPGTT with the GTT */
                struct i915_hw_ppgtt *aliasing_ppgtt;
 
-               u32 *l3_remap_info;
-
                struct shrinker inactive_shrinker;
 
                /**
@@ -827,19 +883,6 @@ typedef struct drm_i915_private {
                u32 object_count;
        } mm;
 
-       /* Old dri1 support infrastructure, beware the dragons ya fools entering
-        * here! */
-       struct {
-               unsigned allow_batchbuffer : 1;
-               u32 __iomem *gfx_hws_cpu_addr;
-
-               unsigned int cpp;
-               int back_offset;
-               int front_offset;
-               int current_page;
-               int page_flipping;
-       } dri1;
-
        /* Kernel Modesetting */
 
        struct sdvo_device_mapping sdvo_mappings[2];
@@ -866,6 +909,8 @@ typedef struct drm_i915_private {
 
        bool mchbar_need_disable;
 
+       struct intel_l3_parity l3_parity;
+
        /* gen6+ rps state */
        struct intel_gen6_power_mgmt rps;
 
@@ -883,16 +928,25 @@ typedef struct drm_i915_private {
        /* list of fbdev register on this device */
        struct intel_fbdev *fbdev;
 
+       /*
+        * The console may be contended at resume, but we don't
+        * want it to block on it.
+        */
+       struct work_struct console_resume_work;
+
        struct backlight_device *backlight;
 
        struct drm_property *broadcast_rgb_property;
        struct drm_property *force_audio_property;
 
-       struct work_struct parity_error_work;
        bool hw_contexts_disabled;
        uint32_t hw_context_size;
 
        struct i915_suspend_saved_registers regfile;
+
+       /* Old dri1 support infrastructure, beware the dragons ya fools entering
+        * here! */
+       struct i915_dri1_state dri1;
 } drm_i915_private_t;
 
 /* Iterate over initialised rings */
@@ -913,6 +967,8 @@ enum i915_cache_level {
        I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */
 };
 
+#define I915_GTT_RESERVED ((struct drm_mm_node *)0x1)
+
 struct drm_i915_gem_object_ops {
        /* Interface between the GEM object and its backing storage.
         * get_pages() is called once prior to the use of the associated set
@@ -938,6 +994,8 @@ struct drm_i915_gem_object {
 
        /** Current space allocated to this object in the GTT, if any. */
        struct drm_mm_node *gtt_space;
+       /** Stolen memory for this object, instead of being backed by shmem. */
+       struct drm_mm_node *stolen;
        struct list_head gtt_list;
 
        /** This object's place on the active/inactive lists */
@@ -1107,7 +1165,7 @@ struct drm_i915_gem_request {
 
 struct drm_i915_file_private {
        struct {
-               struct spinlock lock;
+               spinlock_t lock;
                struct list_head request_list;
        } mm;
        struct idr context_idr;
@@ -1140,6 +1198,8 @@ struct drm_i915_file_private {
 #define IS_VALLEYVIEW(dev)     (INTEL_INFO(dev)->is_valleyview)
 #define IS_HASWELL(dev)        (INTEL_INFO(dev)->is_haswell)
 #define IS_MOBILE(dev)         (INTEL_INFO(dev)->is_mobile)
+#define IS_ULT(dev)            (IS_HASWELL(dev) && \
+                                ((dev)->pci_device & 0xFF00) == 0x0A00)
 
 /*
  * The genX designation typically refers to the render engine, so render
@@ -1185,6 +1245,15 @@ struct drm_i915_file_private {
 
 #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5)
 
+#define HAS_DDI(dev)           (IS_HASWELL(dev))
+
+#define INTEL_PCH_DEVICE_ID_MASK               0xff00
+#define INTEL_PCH_IBX_DEVICE_ID_TYPE           0x3b00
+#define INTEL_PCH_CPT_DEVICE_ID_TYPE           0x1c00
+#define INTEL_PCH_PPT_DEVICE_ID_TYPE           0x1e00
+#define INTEL_PCH_LPT_DEVICE_ID_TYPE           0x8c00
+#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE                0x9c00
+
 #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
 #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
 #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
@@ -1234,6 +1303,7 @@ extern int i915_enable_rc6 __read_mostly;
 extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 extern int i915_enable_ppgtt __read_mostly;
+extern unsigned int i915_preliminary_hw_support __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
@@ -1266,6 +1336,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
 extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
 extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
 
+extern void intel_console_resume(struct work_struct *work);
 
 /* i915_irq.c */
 void i915_hangcheck_elapsed(unsigned long data);
@@ -1340,12 +1411,15 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
 int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 void i915_gem_load(struct drm_device *dev);
+void *i915_gem_object_alloc(struct drm_device *dev);
+void i915_gem_object_free(struct drm_i915_gem_object *obj);
 int i915_gem_init_object(struct drm_gem_object *obj);
 void i915_gem_object_init(struct drm_i915_gem_object *obj,
                         const struct drm_i915_gem_object_ops *ops);
 struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
                                                  size_t size);
 void i915_gem_free_object(struct drm_gem_object *obj);
+
 int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
                                     uint32_t alignment,
                                     bool map_and_fenceable,
@@ -1385,8 +1459,7 @@ int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
                         struct intel_ring_buffer *to);
 void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
-                                   struct intel_ring_buffer *ring,
-                                   u32 seqno);
+                                   struct intel_ring_buffer *ring);
 
 int i915_gem_dumb_create(struct drm_file *file_priv,
                         struct drm_device *dev,
@@ -1404,7 +1477,7 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
        return (int32_t)(seq1 - seq2) >= 0;
 }
 
-u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring);
+extern int i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
 
 int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
 int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
@@ -1516,6 +1589,14 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
                              unsigned long start,
                              unsigned long mappable_end,
                              unsigned long end);
+int i915_gem_gtt_init(struct drm_device *dev);
+void i915_gem_gtt_fini(struct drm_device *dev);
+static inline void i915_gem_chipset_flush(struct drm_device *dev)
+{
+       if (INTEL_INFO(dev)->gen < 6)
+               intel_gtt_chipset_flush();
+}
+
 
 /* i915_gem_evict.c */
 int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
@@ -1527,9 +1608,22 @@ int i915_gem_evict_everything(struct drm_device *dev);
 
 /* i915_gem_stolen.c */
 int i915_gem_init_stolen(struct drm_device *dev);
+int i915_gem_stolen_setup_compression(struct drm_device *dev, int size);
+void i915_gem_stolen_cleanup_compression(struct drm_device *dev);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size);
+void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj);
 
 /* i915_gem_tiling.c */
+inline static bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
+{
+       drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
+
+       return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
+               obj->tiling_mode != I915_TILING_NONE;
+}
+
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
 void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj);
 void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj);
@@ -1612,7 +1706,8 @@ extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_gem_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
 extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
-extern void intel_modeset_setup_hw_state(struct drm_device *dev);
+extern void intel_modeset_setup_hw_state(struct drm_device *dev,
+                                        bool force_restore);
 extern bool intel_fbc_enabled(struct drm_device *dev);
 extern void intel_disable_fbc(struct drm_device *dev);
 extern bool ironlake_set_drps(struct drm_device *dev, u8 val);