]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/i915/i915_drv.h
Merge tag 'drm-intel-next-2017-07-17' of git://anongit.freedesktop.org/git/drm-intel...
[linux.git] / drivers / gpu / drm / i915 / i915_drv.h
index 2c453a4e97d5ba28ca3a21da372f73eed0131268..559fdc7bb39334321f5e430ca19ccd688d6734be 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/backlight.h>
-#include <linux/hashtable.h>
+#include <linux/hash.h>
 #include <linux/intel-iommu.h>
 #include <linux/kref.h>
 #include <linux/pm_qos.h>
@@ -55,6 +55,7 @@
 #include "i915_reg.h"
 #include "i915_utils.h"
 
+#include "intel_uncore.h"
 #include "intel_bios.h"
 #include "intel_dpll_mgr.h"
 #include "intel_uc.h"
@@ -79,8 +80,8 @@
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20170403"
-#define DRIVER_TIMESTAMP       1491198738
+#define DRIVER_DATE            "20170717"
+#define DRIVER_TIMESTAMP       1500275179
 
 /* 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
@@ -114,7 +115,14 @@ typedef struct {
        fp; \
 })
 
-static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
+static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
+{
+       if (val.val == 0)
+               return true;
+       return false;
+}
+
+static inline uint_fixed_16_16_t u32_to_fixed16(uint32_t val)
 {
        uint_fixed_16_16_t fp;
 
@@ -124,17 +132,17 @@ static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
        return fp;
 }
 
-static inline uint32_t fixed_16_16_to_u32_round_up(uint_fixed_16_16_t fp)
+static inline uint32_t fixed16_to_u32_round_up(uint_fixed_16_16_t fp)
 {
        return DIV_ROUND_UP(fp.val, 1 << 16);
 }
 
-static inline uint32_t fixed_16_16_to_u32(uint_fixed_16_16_t fp)
+static inline uint32_t fixed16_to_u32(uint_fixed_16_16_t fp)
 {
        return fp.val >> 16;
 }
 
-static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
+static inline uint_fixed_16_16_t min_fixed16(uint_fixed_16_16_t min1,
                                                 uint_fixed_16_16_t min2)
 {
        uint_fixed_16_16_t min;
@@ -143,7 +151,7 @@ static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
        return min;
 }
 
-static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
+static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1,
                                                 uint_fixed_16_16_t max2)
 {
        uint_fixed_16_16_t max;
@@ -152,40 +160,87 @@ static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
        return max;
 }
 
-static inline uint_fixed_16_16_t fixed_16_16_div_round_up(uint32_t val,
-                                                         uint32_t d)
+static inline uint_fixed_16_16_t clamp_u64_to_fixed16(uint64_t val)
 {
-       uint_fixed_16_16_t fp, res;
+       uint_fixed_16_16_t fp;
+       WARN_ON(val >> 32);
+       fp.val = clamp_t(uint32_t, val, 0, ~0);
+       return fp;
+}
 
-       fp = u32_to_fixed_16_16(val);
-       res.val = DIV_ROUND_UP(fp.val, d);
-       return res;
+static inline uint32_t div_round_up_fixed16(uint_fixed_16_16_t val,
+                                           uint_fixed_16_16_t d)
+{
+       return DIV_ROUND_UP(val.val, d.val);
 }
 
-static inline uint_fixed_16_16_t fixed_16_16_div_round_up_u64(uint32_t val,
-                                                             uint32_t d)
+static inline uint32_t mul_round_up_u32_fixed16(uint32_t val,
+                                               uint_fixed_16_16_t mul)
+{
+       uint64_t intermediate_val;
+
+       intermediate_val = (uint64_t) val * mul.val;
+       intermediate_val = DIV_ROUND_UP_ULL(intermediate_val, 1 << 16);
+       WARN_ON(intermediate_val >> 32);
+       return clamp_t(uint32_t, intermediate_val, 0, ~0);
+}
+
+static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val,
+                                            uint_fixed_16_16_t mul)
+{
+       uint64_t intermediate_val;
+
+       intermediate_val = (uint64_t) val.val * mul.val;
+       intermediate_val = intermediate_val >> 16;
+       return clamp_u64_to_fixed16(intermediate_val);
+}
+
+static inline uint_fixed_16_16_t div_fixed16(uint32_t val, uint32_t d)
 {
-       uint_fixed_16_16_t res;
        uint64_t interm_val;
 
        interm_val = (uint64_t)val << 16;
        interm_val = DIV_ROUND_UP_ULL(interm_val, d);
-       WARN_ON(interm_val >> 32);
-       res.val = (uint32_t) interm_val;
+       return clamp_u64_to_fixed16(interm_val);
+}
+
+static inline uint32_t div_round_up_u32_fixed16(uint32_t val,
+                                               uint_fixed_16_16_t d)
+{
+       uint64_t interm_val;
 
-       return res;
+       interm_val = (uint64_t)val << 16;
+       interm_val = DIV_ROUND_UP_ULL(interm_val, d.val);
+       WARN_ON(interm_val >> 32);
+       return clamp_t(uint32_t, interm_val, 0, ~0);
 }
 
-static inline uint_fixed_16_16_t mul_u32_fixed_16_16(uint32_t val,
+static inline uint_fixed_16_16_t mul_u32_fixed16(uint32_t val,
                                                     uint_fixed_16_16_t mul)
 {
        uint64_t intermediate_val;
-       uint_fixed_16_16_t fp;
 
        intermediate_val = (uint64_t) val * mul.val;
-       WARN_ON(intermediate_val >> 32);
-       fp.val = (uint32_t) intermediate_val;
-       return fp;
+       return clamp_u64_to_fixed16(intermediate_val);
+}
+
+static inline uint_fixed_16_16_t add_fixed16(uint_fixed_16_16_t add1,
+                                            uint_fixed_16_16_t add2)
+{
+       uint64_t interm_sum;
+
+       interm_sum = (uint64_t) add1.val + add2.val;
+       return clamp_u64_to_fixed16(interm_sum);
+}
+
+static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1,
+                                                uint32_t add2)
+{
+       uint64_t interm_sum;
+       uint_fixed_16_16_t interm_add2 = u32_to_fixed16(add2);
+
+       interm_sum = (uint64_t) add1.val + interm_add2.val;
+       return clamp_u64_to_fixed16(interm_sum);
 }
 
 static inline const char *yesno(bool v)
@@ -535,8 +590,7 @@ struct drm_i915_file_private {
        struct idr context_idr;
 
        struct intel_rps_client {
-               struct list_head link;
-               unsigned boosts;
+               atomic_t boosts;
        } rps;
 
        unsigned int bsd_engine;
@@ -677,116 +731,6 @@ struct drm_i915_display_funcs {
        void (*load_luts)(struct drm_crtc_state *crtc_state);
 };
 
-enum forcewake_domain_id {
-       FW_DOMAIN_ID_RENDER = 0,
-       FW_DOMAIN_ID_BLITTER,
-       FW_DOMAIN_ID_MEDIA,
-
-       FW_DOMAIN_ID_COUNT
-};
-
-enum forcewake_domains {
-       FORCEWAKE_RENDER = BIT(FW_DOMAIN_ID_RENDER),
-       FORCEWAKE_BLITTER = BIT(FW_DOMAIN_ID_BLITTER),
-       FORCEWAKE_MEDIA = BIT(FW_DOMAIN_ID_MEDIA),
-       FORCEWAKE_ALL = (FORCEWAKE_RENDER |
-                        FORCEWAKE_BLITTER |
-                        FORCEWAKE_MEDIA)
-};
-
-#define FW_REG_READ  (1)
-#define FW_REG_WRITE (2)
-
-enum decoupled_power_domain {
-       GEN9_DECOUPLED_PD_BLITTER = 0,
-       GEN9_DECOUPLED_PD_RENDER,
-       GEN9_DECOUPLED_PD_MEDIA,
-       GEN9_DECOUPLED_PD_ALL
-};
-
-enum decoupled_ops {
-       GEN9_DECOUPLED_OP_WRITE = 0,
-       GEN9_DECOUPLED_OP_READ
-};
-
-enum forcewake_domains
-intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
-                              i915_reg_t reg, unsigned int op);
-
-struct intel_uncore_funcs {
-       void (*force_wake_get)(struct drm_i915_private *dev_priv,
-                              enum forcewake_domains domains);
-       void (*force_wake_put)(struct drm_i915_private *dev_priv,
-                              enum forcewake_domains domains);
-
-       uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv,
-                              i915_reg_t r, bool trace);
-       uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv,
-                              i915_reg_t r, bool trace);
-       uint32_t (*mmio_readl)(struct drm_i915_private *dev_priv,
-                              i915_reg_t r, bool trace);
-       uint64_t (*mmio_readq)(struct drm_i915_private *dev_priv,
-                              i915_reg_t r, bool trace);
-
-       void (*mmio_writeb)(struct drm_i915_private *dev_priv,
-                           i915_reg_t r, uint8_t val, bool trace);
-       void (*mmio_writew)(struct drm_i915_private *dev_priv,
-                           i915_reg_t r, uint16_t val, bool trace);
-       void (*mmio_writel)(struct drm_i915_private *dev_priv,
-                           i915_reg_t r, uint32_t val, bool trace);
-};
-
-struct intel_forcewake_range {
-       u32 start;
-       u32 end;
-
-       enum forcewake_domains domains;
-};
-
-struct intel_uncore {
-       spinlock_t lock; /** lock is also taken in irq contexts. */
-
-       const struct intel_forcewake_range *fw_domains_table;
-       unsigned int fw_domains_table_entries;
-
-       struct notifier_block pmic_bus_access_nb;
-       struct intel_uncore_funcs funcs;
-
-       unsigned fifo_count;
-
-       enum forcewake_domains fw_domains;
-       enum forcewake_domains fw_domains_active;
-
-       u32 fw_set;
-       u32 fw_clear;
-       u32 fw_reset;
-
-       struct intel_uncore_forcewake_domain {
-               enum forcewake_domain_id id;
-               enum forcewake_domains mask;
-               unsigned wake_count;
-               struct hrtimer timer;
-               i915_reg_t reg_set;
-               i915_reg_t reg_ack;
-       } fw_domain[FW_DOMAIN_ID_COUNT];
-
-       int unclaimed_mmio_check;
-};
-
-#define __mask_next_bit(mask) ({                                       \
-       int __idx = ffs(mask) - 1;                                      \
-       mask &= ~BIT(__idx);                                            \
-       __idx;                                                          \
-})
-
-/* Iterate over initialised fw domains */
-#define for_each_fw_domain_masked(domain__, mask__, dev_priv__, tmp__) \
-       for (tmp__ = (mask__); \
-            tmp__ ? (domain__ = &(dev_priv__)->uncore.fw_domain[__mask_next_bit(tmp__)]), 1 : 0;)
-
-#define for_each_fw_domain(domain__, dev_priv__, tmp__) \
-       for_each_fw_domain_masked(domain__, (dev_priv__)->uncore.fw_domains, dev_priv__, tmp__)
-
 #define CSR_VERSION(major, minor)      ((major) << 16 | (minor))
 #define CSR_VERSION_MAJOR(version)     ((version) >> 16)
 #define CSR_VERSION_MINOR(version)     ((version) & 0xffff)
@@ -813,8 +757,8 @@ struct intel_csr {
        func(has_aliasing_ppgtt); \
        func(has_csr); \
        func(has_ddi); \
-       func(has_decoupled_mmio); \
        func(has_dp_mst); \
+       func(has_reset_engine); \
        func(has_fbc); \
        func(has_fpga_dbg); \
        func(has_full_ppgtt); \
@@ -822,8 +766,8 @@ struct intel_csr {
        func(has_gmbus_irq); \
        func(has_gmch_display); \
        func(has_guc); \
+       func(has_guc_ct); \
        func(has_hotplug); \
-       func(has_hw_contexts); \
        func(has_l3_dpf); \
        func(has_llc); \
        func(has_logical_ring_contexts); \
@@ -888,6 +832,8 @@ enum intel_platform {
        INTEL_BROXTON,
        INTEL_KABYLAKE,
        INTEL_GEMINILAKE,
+       INTEL_COFFEELAKE,
+       INTEL_CANNONLAKE,
        INTEL_MAX_PLATFORMS
 };
 
@@ -977,6 +923,7 @@ struct i915_gpu_state {
                enum intel_engine_hangcheck_action hangcheck_action;
                struct i915_address_space *vm;
                int num_requests;
+               u32 reset_count;
 
                /* position of active request inside the ring */
                u32 rq_head, rq_post, rq_tail;
@@ -1026,6 +973,9 @@ struct i915_gpu_state {
                        u32 *pages[0];
                } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
 
+               struct drm_i915_error_object **user_bo;
+               long user_bo_count;
+
                struct drm_i915_error_object *wa_ctx;
 
                struct drm_i915_error_request {
@@ -1206,10 +1156,11 @@ struct i915_psr {
 enum intel_pch {
        PCH_NONE = 0,   /* No PCH present */
        PCH_IBX,        /* Ibexpeak PCH */
-       PCH_CPT,        /* Cougarpoint PCH */
-       PCH_LPT,        /* Lynxpoint PCH */
+       PCH_CPT,        /* Cougarpoint/Pantherpoint PCH */
+       PCH_LPT,        /* Lynxpoint/Wildcatpoint PCH */
        PCH_SPT,        /* Sunrisepoint PCH */
        PCH_KBP,        /* Kabypoint PCH */
+       PCH_CNP,        /* Cannonpoint PCH */
        PCH_NOP,
 };
 
@@ -1218,12 +1169,11 @@ enum intel_sbi_destination {
        SBI_MPHY,
 };
 
-#define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
 #define QUIRK_BACKLIGHT_PRESENT (1<<3)
-#define QUIRK_PIPEB_FORCE (1<<4)
 #define QUIRK_PIN_SWIZZLED_PAGES (1<<5)
+#define QUIRK_INCREASE_T12_DELAY (1<<6)
 
 struct intel_fbdev;
 struct intel_fbc_work;
@@ -1359,13 +1309,10 @@ struct intel_gen6_power_mgmt {
        int last_adj;
        enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
 
-       spinlock_t client_lock;
-       struct list_head clients;
-       bool client_boost;
-
        bool enabled;
        struct delayed_work autoenable_work;
-       unsigned boosts;
+       atomic_t num_waiters;
+       atomic_t boosts;
 
        /* manual wa residency calculations */
        struct intel_rps_ei ei;
@@ -1513,10 +1460,13 @@ struct i915_gem_mm {
        struct list_head fence_list;
 
        /**
-        * Are we in a non-interruptible section of code like
-        * modesetting?
+        * Workqueue to fault in userptr pages, flushed by the execbuf
+        * when required but otherwise left to userspace to try again
+        * on EAGAIN.
         */
-       bool interruptible;
+       struct workqueue_struct *userptr_wq;
+
+       u64 unordered_timeline;
 
        /* the indicator for dispatch video commands on two BSD rings */
        atomic_t bsd_engine_dispatch_index;
@@ -1567,7 +1517,7 @@ struct i915_gpu_error {
         *
         * This is a counter which gets incremented when reset is triggered,
         *
-        * Before the reset commences, the I915_RESET_IN_PROGRESS bit is set
+        * Before the reset commences, the I915_RESET_BACKOFF bit is set
         * meaning that any waiters holding onto the struct_mutex should
         * relinquish the lock immediately in order for the reset to start.
         *
@@ -1605,6 +1555,12 @@ struct i915_gpu_error {
         * inspect the bit and do the reset directly, otherwise the worker
         * waits for the struct_mutex.
         *
+        * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to
+        * acquire the struct_mutex to reset an engine, we need an explicit
+        * flag to prevent two concurrent reset attempts in the same engine.
+        * As the number of engines continues to grow, allocate the flags from
+        * the most significant bits.
+        *
         * #I915_WEDGED - If reset fails and we can no longer use the GPU,
         * we set the #I915_WEDGED bit. Prior to command submission, e.g.
         * i915_gem_request_alloc(), this bit is checked and the sequence
@@ -1614,6 +1570,10 @@ struct i915_gpu_error {
 #define I915_RESET_BACKOFF     0
 #define I915_RESET_HANDOFF     1
 #define I915_WEDGED            (BITS_PER_LONG - 1)
+#define I915_RESET_ENGINE      (I915_WEDGED - I915_NUM_ENGINES)
+
+       /** Number of times an engine has been reset */
+       u32 reset_engine_count[I915_NUM_ENGINES];
 
        /**
         * Waitqueue to signal when a hang is detected. Used to for waiters
@@ -1764,13 +1724,15 @@ struct ilk_wm_values {
        enum intel_ddb_partitioning partitioning;
 };
 
-struct vlv_pipe_wm {
+struct g4x_pipe_wm {
        uint16_t plane[I915_MAX_PLANES];
+       uint16_t fbc;
 };
 
-struct vlv_sr_wm {
+struct g4x_sr_wm {
        uint16_t plane;
        uint16_t cursor;
+       uint16_t fbc;
 };
 
 struct vlv_wm_ddl_values {
@@ -1778,13 +1740,22 @@ struct vlv_wm_ddl_values {
 };
 
 struct vlv_wm_values {
-       struct vlv_pipe_wm pipe[3];
-       struct vlv_sr_wm sr;
+       struct g4x_pipe_wm pipe[3];
+       struct g4x_sr_wm sr;
        struct vlv_wm_ddl_values ddl[3];
        uint8_t level;
        bool cxsr;
 };
 
+struct g4x_wm_values {
+       struct g4x_pipe_wm pipe[2];
+       struct g4x_sr_wm sr;
+       struct g4x_sr_wm hpll;
+       bool cxsr;
+       bool hpll_en;
+       bool fbc_en;
+};
+
 struct skl_ddb_entry {
        uint16_t start, end;    /* in number of blocks, 'end' is exclusive */
 };
@@ -2068,9 +2039,17 @@ struct i915_oa_ops {
        void (*init_oa_buffer)(struct drm_i915_private *dev_priv);
 
        /**
-        * @enable_metric_set: Applies any MUX configuration to set up the
-        * Boolean and Custom (B/C) counters that are part of the counter
-        * reports being sampled. May apply system constraints such as
+        * @select_metric_set: The auto generated code that checks whether a
+        * requested OA config is applicable to the system and if so sets up
+        * the mux, oa and flex eu register config pointers according to the
+        * current dev_priv->perf.oa.metrics_set.
+        */
+       int (*select_metric_set)(struct drm_i915_private *dev_priv);
+
+       /**
+        * @enable_metric_set: Selects and applies any MUX configuration to set
+        * up the Boolean and Custom (B/C) counters that are part of the
+        * counter reports being sampled. May apply system constraints such as
         * disabling EU clock gating as required.
         */
        int (*enable_metric_set)(struct drm_i915_private *dev_priv);
@@ -2101,20 +2080,13 @@ struct i915_oa_ops {
                    size_t *offset);
 
        /**
-        * @oa_buffer_is_empty: Check if OA buffer empty (false positives OK)
-        *
-        * This is either called via fops or the poll check hrtimer (atomic
-        * ctx) without any locks taken.
+        * @oa_hw_tail_read: read the OA tail pointer register
         *
-        * It's safe to read OA config state here unlocked, assuming that this
-        * is only called while the stream is enabled, while the global OA
-        * configuration can't be modified.
-        *
-        * Efficiency is more important than avoiding some false positives
-        * here, which will be handled gracefully - likely resulting in an
-        * %EAGAIN error for userspace.
+        * In particular this enables us to share all the fiddly code for
+        * handling the OA unit tail pointer race that affects multiple
+        * generations.
         */
-       bool (*oa_buffer_is_empty)(struct drm_i915_private *dev_priv);
+       u32 (*oa_hw_tail_read)(struct drm_i915_private *dev_priv);
 };
 
 struct intel_cdclk_state {
@@ -2128,6 +2100,7 @@ struct drm_i915_private {
        struct kmem_cache *vmas;
        struct kmem_cache *requests;
        struct kmem_cache *dependencies;
+       struct kmem_cache *priorities;
 
        const struct intel_device_info info;
 
@@ -2278,13 +2251,6 @@ struct drm_i915_private {
        DECLARE_HASHTABLE(mm_structs, 7);
        struct mutex mm_lock;
 
-       /* The hw wants to have a stable context identifier for the lifetime
-        * of the context (for OA, PASID, faults, etc). This is limited
-        * in execlists to 21 bits.
-        */
-       struct ida context_hw_ida;
-#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
-
        /* Kernel Modesetting */
 
        struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
@@ -2363,8 +2329,18 @@ struct drm_i915_private {
         */
        struct mutex av_mutex;
 
-       uint32_t hw_context_size;
-       struct list_head context_list;
+       struct {
+               struct list_head list;
+               struct llist_head free_list;
+               struct work_struct free_work;
+
+               /* The hw wants to have a stable context identifier for the
+                * lifetime of the context (for OA, PASID, faults, etc).
+                * This is limited in execlists to 21 bits.
+                */
+               struct ida hw_ida;
+#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
+       } contexts;
 
        u32 fdi_rx_config;
 
@@ -2414,6 +2390,7 @@ struct drm_i915_private {
                        struct ilk_wm_values hw;
                        struct skl_wm_values skl_hw;
                        struct vlv_wm_values vlv;
+                       struct g4x_wm_values g4x;
                };
 
                uint8_t max_level;
@@ -2444,8 +2421,6 @@ struct drm_i915_private {
                struct mutex lock;
                struct list_head streams;
 
-               spinlock_t hook_lock;
-
                struct {
                        struct i915_perf_stream *exclusive_stream;
 
@@ -2455,27 +2430,109 @@ struct drm_i915_private {
                        wait_queue_head_t poll_wq;
                        bool pollin;
 
+                       /**
+                        * For rate limiting any notifications of spurious
+                        * invalid OA reports
+                        */
+                       struct ratelimit_state spurious_report_rs;
+
                        bool periodic;
                        int period_exponent;
                        int timestamp_frequency;
 
-                       int tail_margin;
-
                        int metrics_set;
 
-                       const struct i915_oa_reg *mux_regs;
-                       int mux_regs_len;
+                       const struct i915_oa_reg *mux_regs[6];
+                       int mux_regs_lens[6];
+                       int n_mux_configs;
+
                        const struct i915_oa_reg *b_counter_regs;
                        int b_counter_regs_len;
+                       const struct i915_oa_reg *flex_regs;
+                       int flex_regs_len;
 
                        struct {
                                struct i915_vma *vma;
                                u8 *vaddr;
+                               u32 last_ctx_id;
                                int format;
                                int format_size;
+
+                               /**
+                                * Locks reads and writes to all head/tail state
+                                *
+                                * Consider: the head and tail pointer state
+                                * needs to be read consistently from a hrtimer
+                                * callback (atomic context) and read() fop
+                                * (user context) with tail pointer updates
+                                * happening in atomic context and head updates
+                                * in user context and the (unlikely)
+                                * possibility of read() errors needing to
+                                * reset all head/tail state.
+                                *
+                                * Note: Contention or performance aren't
+                                * currently a significant concern here
+                                * considering the relatively low frequency of
+                                * hrtimer callbacks (5ms period) and that
+                                * reads typically only happen in response to a
+                                * hrtimer event and likely complete before the
+                                * next callback.
+                                *
+                                * Note: This lock is not held *while* reading
+                                * and copying data to userspace so the value
+                                * of head observed in htrimer callbacks won't
+                                * represent any partial consumption of data.
+                                */
+                               spinlock_t ptr_lock;
+
+                               /**
+                                * One 'aging' tail pointer and one 'aged'
+                                * tail pointer ready to used for reading.
+                                *
+                                * Initial values of 0xffffffff are invalid
+                                * and imply that an update is required
+                                * (and should be ignored by an attempted
+                                * read)
+                                */
+                               struct {
+                                       u32 offset;
+                               } tails[2];
+
+                               /**
+                                * Index for the aged tail ready to read()
+                                * data up to.
+                                */
+                               unsigned int aged_tail_idx;
+
+                               /**
+                                * A monotonic timestamp for when the current
+                                * aging tail pointer was read; used to
+                                * determine when it is old enough to trust.
+                                */
+                               u64 aging_timestamp;
+
+                               /**
+                                * Although we can always read back the head
+                                * pointer register, we prefer to avoid
+                                * trusting the HW state, just to avoid any
+                                * risk that some hardware condition could
+                                * somehow bump the head pointer unpredictably
+                                * and cause us to forward the wrong OA buffer
+                                * data to userspace.
+                                */
+                               u32 head;
                        } oa_buffer;
 
                        u32 gen7_latched_oastatus1;
+                       u32 ctx_oactxctrl_offset;
+                       u32 ctx_flexeu0_offset;
+
+                       /**
+                        * The RPT_ID/reason field for Gen8+ includes a bit
+                        * to determine if the CTX ID in the report is valid
+                        * but the specific bit differs between Gen 8 and 9
+                        */
+                       u32 gen8_valid_ctx_bit;
 
                        struct i915_oa_ops ops;
                        const struct i915_oa_format *oa_formats;
@@ -2751,6 +2808,8 @@ intel_info(const struct drm_i915_private *dev_priv)
 #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_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)
@@ -2786,10 +2845,18 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define IS_KBL_ULX(dev_priv)   (INTEL_DEVID(dev_priv) == 0x590E || \
                                 INTEL_DEVID(dev_priv) == 0x5915 || \
                                 INTEL_DEVID(dev_priv) == 0x591E)
+#define IS_SKL_GT2(dev_priv)   (IS_SKYLAKE(dev_priv) && \
+                                (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0010)
 #define IS_SKL_GT3(dev_priv)   (IS_SKYLAKE(dev_priv) && \
                                 (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0020)
 #define IS_SKL_GT4(dev_priv)   (IS_SKYLAKE(dev_priv) && \
                                 (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0030)
+#define IS_KBL_GT2(dev_priv)   (IS_KABYLAKE(dev_priv) && \
+                                (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0010)
+#define IS_KBL_GT3(dev_priv)   (IS_KABYLAKE(dev_priv) && \
+                                (INTEL_DEVID(dev_priv) & 0x00F0) == 0x0020)
+#define IS_CFL_ULT(dev_priv)   (IS_COFFEELAKE(dev_priv) && \
+                                (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0)
 
 #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support)
 
@@ -2828,6 +2895,12 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define IS_GLK_REVID(dev_priv, since, until) \
        (IS_GEMINILAKE(dev_priv) && IS_REVID(dev_priv, since, until))
 
+#define CNL_REVID_A0           0x0
+#define CNL_REVID_B0           0x1
+
+#define IS_CNL_REVID(p, since, until) \
+       (IS_CANNONLAKE(p) && IS_REVID(p, since, until))
+
 /*
  * The genX designation typically refers to the render engine, so render
  * capability related checks should use IS_GEN, while display and other checks
@@ -2842,6 +2915,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define IS_GEN7(dev_priv)      (!!((dev_priv)->info.gen_mask & BIT(6)))
 #define IS_GEN8(dev_priv)      (!!((dev_priv)->info.gen_mask & BIT(7)))
 #define IS_GEN9(dev_priv)      (!!((dev_priv)->info.gen_mask & BIT(8)))
+#define IS_GEN10(dev_priv)     (!!((dev_priv)->info.gen_mask & BIT(9)))
 
 #define IS_LP(dev_priv)        (INTEL_INFO(dev_priv)->is_lp)
 #define IS_GEN9_LP(dev_priv)   (IS_GEN9(dev_priv) && IS_LP(dev_priv))
@@ -2871,7 +2945,6 @@ intel_info(const struct drm_i915_private *dev_priv)
 
 #define HWS_NEEDS_PHYSICAL(dev_priv)   ((dev_priv)->info.hws_needs_physical)
 
-#define HAS_HW_CONTEXTS(dev_priv)          ((dev_priv)->info.has_hw_contexts)
 #define HAS_LOGICAL_RING_CONTEXTS(dev_priv) \
                ((dev_priv)->info.has_logical_ring_contexts)
 #define USES_PPGTT(dev_priv)           (i915.enable_ppgtt)
@@ -2910,6 +2983,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define HAS_FW_BLC(dev_priv)   (INTEL_GEN(dev_priv) > 2)
 #define HAS_PIPE_CXSR(dev_priv) ((dev_priv)->info.has_pipe_cxsr)
 #define HAS_FBC(dev_priv)      ((dev_priv)->info.has_fbc)
+#define HAS_CUR_FBC(dev_priv)  (!HAS_GMCH_DISPLAY(dev_priv) && INTEL_INFO(dev_priv)->gen >= 7)
 
 #define HAS_IPS(dev_priv)      (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv))
 
@@ -2932,6 +3006,7 @@ intel_info(const struct drm_i915_private *dev_priv)
  * properties, so we have separate macros to test them.
  */
 #define HAS_GUC(dev_priv)      ((dev_priv)->info.has_guc)
+#define HAS_GUC_CT(dev_priv)   ((dev_priv)->info.has_guc_ct)
 #define HAS_GUC_UCODE(dev_priv)        (HAS_GUC(dev_priv))
 #define HAS_GUC_SCHED(dev_priv)        (HAS_GUC(dev_priv))
 #define HAS_HUC_UCODE(dev_priv)        (HAS_GUC(dev_priv))
@@ -2940,27 +3015,36 @@ intel_info(const struct drm_i915_private *dev_priv)
 
 #define HAS_POOLED_EU(dev_priv)        ((dev_priv)->info.has_pooled_eu)
 
-#define INTEL_PCH_DEVICE_ID_MASK               0xff00
+#define INTEL_PCH_DEVICE_ID_MASK               0xff80
 #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_WPT_DEVICE_ID_TYPE           0x8c80
+#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE                0x9c80
 #define INTEL_PCH_SPT_DEVICE_ID_TYPE           0xA100
 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE                0x9D00
-#define INTEL_PCH_KBP_DEVICE_ID_TYPE           0xA200
+#define INTEL_PCH_KBP_DEVICE_ID_TYPE           0xA280
+#define INTEL_PCH_CNP_DEVICE_ID_TYPE           0xA300
+#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE                0x9D80
 #define INTEL_PCH_P2X_DEVICE_ID_TYPE           0x7100
 #define INTEL_PCH_P3X_DEVICE_ID_TYPE           0x7000
 #define INTEL_PCH_QEMU_DEVICE_ID_TYPE          0x2900 /* qemu q35 has 2918 */
 
 #define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type)
+#define HAS_PCH_CNP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CNP)
+#define HAS_PCH_CNP_LP(dev_priv) \
+       ((dev_priv)->pch_id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE)
 #define HAS_PCH_KBP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_KBP)
 #define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT)
 #define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT)
 #define HAS_PCH_LPT_LP(dev_priv) \
-       ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
+       ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \
+        (dev_priv)->pch_id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE)
 #define HAS_PCH_LPT_H(dev_priv) \
-       ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE)
+       ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE || \
+        (dev_priv)->pch_id == INTEL_PCH_WPT_DEVICE_ID_TYPE)
 #define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT)
 #define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX)
 #define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP)
@@ -2968,7 +3052,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 
 #define HAS_GMCH_DISPLAY(dev_priv) ((dev_priv)->info.has_gmch_display)
 
-#define HAS_LSPCON(dev_priv) (IS_GEN9(dev_priv))
+#define HAS_LSPCON(dev_priv) (INTEL_GEN(dev_priv) >= 9)
 
 /* DPF == dynamic parity feature */
 #define HAS_L3_DPF(dev_priv) ((dev_priv)->info.has_l3_dpf)
@@ -2978,27 +3062,26 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define GT_FREQUENCY_MULTIPLIER 50
 #define GEN9_FREQ_SCALER 3
 
-#define HAS_DECOUPLED_MMIO(dev_priv) (INTEL_INFO(dev_priv)->has_decoupled_mmio)
-
 #include "i915_trace.h"
 
-static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv)
+static inline bool intel_vtd_active(void)
 {
 #ifdef CONFIG_INTEL_IOMMU
-       if (INTEL_GEN(dev_priv) >= 6 && intel_iommu_gfx_mapped)
+       if (intel_iommu_gfx_mapped)
                return true;
 #endif
        return false;
 }
 
+static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv)
+{
+       return INTEL_GEN(dev_priv) >= 6 && intel_vtd_active();
+}
+
 static inline bool
 intel_ggtt_update_needs_vtd_wa(struct drm_i915_private *dev_priv)
 {
-#ifdef CONFIG_INTEL_IOMMU
-       if (IS_BROXTON(dev_priv) && intel_iommu_gfx_mapped)
-               return true;
-#endif
-       return false;
+       return IS_BROXTON(dev_priv) && intel_vtd_active();
 }
 
 int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
@@ -3028,6 +3111,8 @@ extern void i915_driver_unload(struct drm_device *dev);
 extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask);
 extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv);
 extern void i915_reset(struct drm_i915_private *dev_priv);
+extern int i915_reset_engine(struct intel_engine_cs *engine);
+extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv);
 extern int intel_guc_reset(struct drm_i915_private *dev_priv);
 extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
 extern void intel_hangcheck_init(struct drm_i915_private *dev_priv);
@@ -3037,7 +3122,7 @@ extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
 extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
 int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
 
-int intel_engines_init_early(struct drm_i915_private *dev_priv);
+int intel_engines_init_mmio(struct drm_i915_private *dev_priv);
 int intel_engines_init(struct drm_i915_private *dev_priv);
 
 /* intel_hotplug.c */
@@ -3074,43 +3159,10 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
                       const char *fmt, ...);
 
 extern void intel_irq_init(struct drm_i915_private *dev_priv);
+extern void intel_irq_fini(struct drm_i915_private *dev_priv);
 int intel_irq_install(struct drm_i915_private *dev_priv);
 void intel_irq_uninstall(struct drm_i915_private *dev_priv);
 
-extern void intel_uncore_sanitize(struct drm_i915_private *dev_priv);
-extern void intel_uncore_init(struct drm_i915_private *dev_priv);
-extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
-extern bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
-extern void intel_uncore_fini(struct drm_i915_private *dev_priv);
-extern void intel_uncore_suspend(struct drm_i915_private *dev_priv);
-extern void intel_uncore_resume_early(struct drm_i915_private *dev_priv);
-const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
-void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
-                               enum forcewake_domains domains);
-void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
-                               enum forcewake_domains domains);
-/* Like above but the caller must manage the uncore.lock itself.
- * Must be used with I915_READ_FW and friends.
- */
-void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
-                                       enum forcewake_domains domains);
-void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
-                                       enum forcewake_domains domains);
-u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv);
-
-void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
-
-int intel_wait_for_register(struct drm_i915_private *dev_priv,
-                           i915_reg_t reg,
-                           const u32 mask,
-                           const u32 value,
-                           const unsigned long timeout_ms);
-int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
-                              i915_reg_t reg,
-                              const u32 mask,
-                              const u32 value,
-                              const unsigned long timeout_ms);
-
 static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
 {
        return dev_priv->gvt;
@@ -3208,7 +3260,8 @@ int i915_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
                              struct drm_file *file_priv);
 int i915_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
                              struct drm_file *file_priv);
-void i915_gem_init_userptr(struct drm_i915_private *dev_priv);
+int i915_gem_init_userptr(struct drm_i915_private *dev_priv);
+void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
 int i915_gem_userptr_ioctl(struct drm_device *dev, void *data,
                           struct drm_file *file);
 int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
@@ -3432,11 +3485,22 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
        return READ_ONCE(error->reset_count);
 }
 
+static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
+                                         struct intel_engine_cs *engine)
+{
+       return READ_ONCE(error->reset_engine_count[engine->id]);
+}
+
+struct drm_i915_gem_request *
+i915_gem_reset_prepare_engine(struct intel_engine_cs *engine);
 int i915_gem_reset_prepare(struct drm_i915_private *dev_priv);
 void i915_gem_reset(struct drm_i915_private *dev_priv);
+void i915_gem_reset_finish_engine(struct intel_engine_cs *engine);
 void i915_gem_reset_finish(struct drm_i915_private *dev_priv);
 void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
 bool i915_gem_unset_wedged(struct drm_i915_private *dev_priv);
+void i915_gem_reset_engine(struct intel_engine_cs *engine,
+                          struct drm_i915_gem_request *request);
 
 void i915_gem_init_mmio(struct drm_i915_private *i915);
 int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
@@ -3458,8 +3522,9 @@ int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
 #define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX
 
 int __must_check
-i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
-                                 bool write);
+i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write);
+int __must_check
+i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write);
 int __must_check
 i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
 struct i915_vma * __must_check
@@ -3469,7 +3534,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
 int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
                                int align);
-int i915_gem_open(struct drm_device *dev, struct drm_file *file);
+int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
 void i915_gem_release(struct drm_device *dev, struct drm_file *file);
 
 int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
@@ -3501,38 +3566,23 @@ void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
                                         struct sg_table *pages);
 
 static inline struct i915_gem_context *
-i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
+__i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
 {
-       struct i915_gem_context *ctx;
-
-       lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex);
-
-       ctx = idr_find(&file_priv->context_idr, id);
-       if (!ctx)
-               return ERR_PTR(-ENOENT);
-
-       return ctx;
+       return idr_find(&file_priv->context_idr, id);
 }
 
 static inline struct i915_gem_context *
-i915_gem_context_get(struct i915_gem_context *ctx)
-{
-       kref_get(&ctx->ref);
-       return ctx;
-}
-
-static inline void i915_gem_context_put(struct i915_gem_context *ctx)
+i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
 {
-       lockdep_assert_held(&ctx->i915->drm.struct_mutex);
-       kref_put(&ctx->ref, i915_gem_context_free);
-}
+       struct i915_gem_context *ctx;
 
-static inline void i915_gem_context_put_unlocked(struct i915_gem_context *ctx)
-{
-       struct mutex *lock = &ctx->i915->drm.struct_mutex;
+       rcu_read_lock();
+       ctx = __i915_gem_context_lookup_rcu(file_priv, id);
+       if (ctx && !kref_get_unless_zero(&ctx->ref))
+               ctx = NULL;
+       rcu_read_unlock();
 
-       if (kref_put_mutex(&ctx->ref, i915_gem_context_free, lock))
-               mutex_unlock(lock);
+       return ctx;
 }
 
 static inline struct intel_timeline *
@@ -3547,6 +3597,9 @@ i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
 
 int i915_perf_open_ioctl(struct drm_device *dev, void *data,
                         struct drm_file *file);
+void i915_oa_init_reg_state(struct intel_engine_cs *engine,
+                           struct i915_gem_context *ctx,
+                           uint32_t *reg_state);
 
 /* i915_gem_evict.c */
 int __must_check i915_gem_evict_something(struct i915_address_space *vm,
@@ -3557,7 +3610,7 @@ int __must_check i915_gem_evict_something(struct i915_address_space *vm,
 int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
                                         struct drm_mm_node *node,
                                         unsigned int flags);
-int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
+int i915_gem_evict_vm(struct i915_address_space *vm);
 
 /* belongs in i915_gem_gtt.h */
 static inline void i915_gem_chipset_flush(struct drm_i915_private *dev_priv)
@@ -3722,8 +3775,8 @@ int  intel_lpe_audio_init(struct drm_i915_private *dev_priv);
 void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv);
 void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv);
 void intel_lpe_audio_notify(struct drm_i915_private *dev_priv,
-                           void *eld, int port, int pipe, int tmds_clk_speed,
-                           bool dp_output, int link_rate);
+                           enum pipe pipe, enum port port,
+                           const void *eld, int ls_clock, bool dp_output);
 
 /* intel_i2c.c */
 extern int intel_setup_gmbus(struct drm_i915_private *dev_priv);