Merge remote-tracking branch 'drm-intel/for-linux-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Fri, 8 Feb 2019 01:01:09 +0000 (12:01 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 8 Feb 2019 01:01:09 +0000 (12:01 +1100)
1  2 
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_pmu.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_overlay.c

   *
   */
  
 -#include <linux/debugfs.h>
  #include <linux/sort.h>
  #include <linux/sched/mm.h>
 +#include <drm/drm_debugfs.h>
 +#include <drm/drm_fourcc.h>
  #include "intel_drv.h"
  #include "intel_guc_submission.h"
  
@@@ -207,7 -206,7 +207,7 @@@ describe_obj(struct seq_file *m, struc
                if (vma->fence)
                        seq_printf(m, " , fence: %d%s",
                                   vma->fence->id,
-                                  i915_gem_active_isset(&vma->last_fence) ? "*" : "");
+                                  i915_active_request_isset(&vma->last_fence) ? "*" : "");
                seq_puts(m, ")");
        }
        if (obj->stolen)
@@@ -2607,7 -2606,6 +2607,6 @@@ static in
  i915_edp_psr_debug_set(void *data, u64 val)
  {
        struct drm_i915_private *dev_priv = data;
-       struct drm_modeset_acquire_ctx ctx;
        intel_wakeref_t wakeref;
        int ret;
  
  
        wakeref = intel_runtime_pm_get(dev_priv);
  
-       drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
- retry:
-       ret = intel_psr_set_debugfs_mode(dev_priv, &ctx, val);
-       if (ret == -EDEADLK) {
-               ret = drm_modeset_backoff(&ctx);
-               if (!ret)
-                       goto retry;
-       }
-       drm_modeset_drop_locks(&ctx);
-       drm_modeset_acquire_fini(&ctx);
+       ret = intel_psr_debug_set(dev_priv, val);
  
        intel_runtime_pm_put(dev_priv, wakeref);
  
@@@ -3728,7 -3715,7 +3716,7 @@@ static int spr_wm_latency_open(struct i
  {
        struct drm_i915_private *dev_priv = inode->i_private;
  
-       if (HAS_GMCH_DISPLAY(dev_priv))
+       if (HAS_GMCH(dev_priv))
                return -ENODEV;
  
        return single_open(file, spr_wm_latency_show, dev_priv);
@@@ -3738,7 -3725,7 +3726,7 @@@ static int cur_wm_latency_open(struct i
  {
        struct drm_i915_private *dev_priv = inode->i_private;
  
-       if (HAS_GMCH_DISPLAY(dev_priv))
+       if (HAS_GMCH(dev_priv))
                return -ENODEV;
  
        return single_open(file, cur_wm_latency_show, dev_priv);
@@@ -41,7 -41,7 +41,7 @@@
  #include <linux/vt.h>
  #include <acpi/video.h>
  
 -#include <drm/drm_crtc_helper.h>
 +#include <drm/drm_probe_helper.h>
  #include <drm/drm_atomic_helper.h>
  #include <drm/i915_drm.h>
  
@@@ -2543,6 -2543,10 +2543,10 @@@ static void vlv_restore_gunit_s0ix_stat
  static int vlv_wait_for_pw_status(struct drm_i915_private *dev_priv,
                                  u32 mask, u32 val)
  {
+       i915_reg_t reg = VLV_GTLC_PW_STATUS;
+       u32 reg_value;
+       int ret;
        /* The HW does not like us polling for PW_STATUS frequently, so
         * use the sleeping loop rather than risk the busy spin within
         * intel_wait_for_register().
         * Transitioning between RC6 states should be at most 2ms (see
         * valleyview_enable_rps) so use a 3ms timeout.
         */
-       return wait_for((I915_READ_NOTRACE(VLV_GTLC_PW_STATUS) & mask) == val,
-                       3);
+       ret = wait_for(((reg_value = I915_READ_NOTRACE(reg)) & mask) == val, 3);
+       /* just trace the final value */
+       trace_i915_reg_rw(false, reg, reg_value, sizeof(reg_value), true);
+       return ret;
  }
  
  int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
@@@ -3010,7 -3018,7 +3018,7 @@@ static struct drm_driver driver = 
         * deal with them for Intel hardware.
         */
        .driver_features =
 -          DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
 +          DRIVER_GEM | DRIVER_PRIME |
            DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ,
        .release = i915_driver_release,
        .open = i915_driver_open,
@@@ -26,7 -26,6 +26,7 @@@
   */
  
  #include <drm/drm_vma_manager.h>
 +#include <drm/drm_pci.h>
  #include <drm/i915_drm.h>
  #include <linux/dma-fence-array.h>
  #include <linux/kthread.h>
@@@ -37,7 -36,6 +37,7 @@@
  #include <linux/swap.h>
  #include <linux/pci.h>
  #include <linux/dma-buf.h>
 +#include <linux/mman.h>
  
  #include "i915_drv.h"
  #include "i915_gem_clflush.h"
@@@ -1681,6 -1679,16 +1681,16 @@@ i915_gem_sw_finish_ioctl(struct drm_dev
        return 0;
  }
  
+ static inline bool
+ __vma_matches(struct vm_area_struct *vma, struct file *filp,
+             unsigned long addr, unsigned long size)
+ {
+       if (vma->vm_file != filp)
+               return false;
+       return vma->vm_start == addr && (vma->vm_end - vma->vm_start) == size;
+ }
  /**
   * i915_gem_mmap_ioctl - Maps the contents of an object, returning the address
   *                     it is mapped to.
@@@ -1730,6 -1738,9 +1740,9 @@@ i915_gem_mmap_ioctl(struct drm_device *
        addr = vm_mmap(obj->base.filp, 0, args->size,
                       PROT_READ | PROT_WRITE, MAP_SHARED,
                       args->offset);
+       if (IS_ERR_VALUE(addr))
+               goto err;
        if (args->flags & I915_MMAP_WC) {
                struct mm_struct *mm = current->mm;
                struct vm_area_struct *vma;
                        return -EINTR;
                }
                vma = find_vma(mm, addr);
-               if (vma)
+               if (vma && __vma_matches(vma, obj->base.filp, addr, args->size))
                        vma->vm_page_prot =
                                pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
                else
                        addr = -ENOMEM;
                up_write(&mm->mmap_sem);
+               if (IS_ERR_VALUE(addr))
+                       goto err;
  
                /* This may race, but that's ok, it only gets set */
                WRITE_ONCE(obj->frontbuffer_ggtt_origin, ORIGIN_CPU);
        }
        i915_gem_object_put(obj);
-       if (IS_ERR((void *)addr))
-               return addr;
  
        args->addr_ptr = (u64)addr;
  
        return 0;
+ err:
+       i915_gem_object_put(obj);
+       return addr;
  }
  
  static unsigned int tile_row_pages(const struct drm_i915_gem_object *obj)
@@@ -3020,7 -3036,7 +3038,7 @@@ static void assert_kernel_context_is_cu
  
        GEM_BUG_ON(i915->gt.active_requests);
        for_each_engine(engine, i915, id) {
-               GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline.last_request));
+               GEM_BUG_ON(__i915_active_request_peek(&engine->timeline.last_request));
                GEM_BUG_ON(engine->last_retired_context !=
                           to_intel_context(i915->kernel_context, engine));
        }
@@@ -3266,7 -3282,7 +3284,7 @@@ wait_for_timelines(struct drm_i915_priv
        list_for_each_entry(tl, &gt->active_list, link) {
                struct i915_request *rq;
  
-               rq = i915_gem_active_get_unlocked(&tl->last_request);
+               rq = i915_active_request_get_unlocked(&tl->last_request);
                if (!rq)
                        continue;
  
@@@ -4167,7 -4183,8 +4185,8 @@@ out
  }
  
  static void
- frontbuffer_retire(struct i915_gem_active *active, struct i915_request *request)
+ frontbuffer_retire(struct i915_active_request *active,
+                  struct i915_request *request)
  {
        struct drm_i915_gem_object *obj =
                container_of(active, typeof(*obj), frontbuffer_write);
@@@ -4194,7 -4211,8 +4213,8 @@@ void i915_gem_object_init(struct drm_i9
        obj->resv = &obj->__builtin_resv;
  
        obj->frontbuffer_ggtt_origin = ORIGIN_GTT;
-       init_request_active(&obj->frontbuffer_write, frontbuffer_retire);
+       i915_active_request_init(&obj->frontbuffer_write,
+                                NULL, frontbuffer_retire);
  
        obj->mm.madv = I915_MADV_WILLNEED;
        INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
@@@ -26,8 -26,7 +26,9 @@@
  #include <linux/vgaarb.h>
  #include <linux/vga_switcheroo.h>
  
 +#include <drm/drm_drv.h>
 +
+ #include "i915_active.h"
  #include "i915_drv.h"
  #include "i915_selftest.h"
  
@@@ -89,7 -88,7 +90,7 @@@
        .num_pipes = 1, \
        .display.has_overlay = 1, \
        .display.overlay_needs_physical = 1, \
-       .display.has_gmch_display = 1, \
+       .display.has_gmch = 1, \
        .gpu_reset_clobbers_display = true, \
        .hws_needs_physical = 1, \
        .unfenced_needs_alignment = 1, \
@@@ -130,7 -129,7 +131,7 @@@ static const struct intel_device_info i
  #define GEN3_FEATURES \
        GEN(3), \
        .num_pipes = 2, \
-       .display.has_gmch_display = 1, \
+       .display.has_gmch = 1, \
        .gpu_reset_clobbers_display = true, \
        .ring_mask = RENDER_RING, \
        .has_snoop = true, \
@@@ -207,7 -206,7 +208,7 @@@ static const struct intel_device_info i
        GEN(4), \
        .num_pipes = 2, \
        .display.has_hotplug = 1, \
-       .display.has_gmch_display = 1, \
+       .display.has_gmch = 1, \
        .gpu_reset_clobbers_display = true, \
        .ring_mask = RENDER_RING, \
        .has_snoop = true, \
@@@ -383,7 -382,7 +384,7 @@@ static const struct intel_device_info i
        .num_pipes = 2,
        .has_runtime_pm = 1,
        .has_rc6 = 1,
-       .display.has_gmch_display = 1,
+       .display.has_gmch = 1,
        .display.has_hotplug = 1,
        .ppgtt = INTEL_PPGTT_FULL,
        .has_snoop = true,
@@@ -475,7 -474,7 +476,7 @@@ static const struct intel_device_info i
        .has_runtime_pm = 1,
        .has_rc6 = 1,
        .has_logical_ring_contexts = 1,
-       .display.has_gmch_display = 1,
+       .display.has_gmch = 1,
        .ppgtt = INTEL_PPGTT_FULL,
        .has_reset_engine = 1,
        .has_snoop = true,
@@@ -800,6 -799,8 +801,8 @@@ static int __init i915_init(void
        bool use_kms = true;
        int err;
  
+       i915_global_active_init();
        err = i915_mock_selftests();
        if (err)
                return err > 0 ? 0 : err;
@@@ -831,6 -832,7 +834,7 @@@ static void __exit i915_exit(void
                return;
  
        pci_unregister_driver(&i915_pci_driver);
+       i915_global_active_exit();
  }
  
  module_init(i915_init);
@@@ -5,7 -5,6 +5,7 @@@
   */
  
  #include <linux/irq.h>
 +#include <linux/pm_runtime.h>
  #include "i915_pmu.h"
  #include "intel_ringbuffer.h"
  #include "i915_drv.h"
@@@ -484,6 -483,7 +484,6 @@@ static u64 get_rc6(struct drm_i915_priv
                 * counter value.
                 */
                spin_lock_irqsave(&i915->pmu.lock, flags);
 -              spin_lock(&kdev->power.lock);
  
                /*
                 * After the above branch intel_runtime_pm_get_if_in_use failed
                 * suspended and if not we cannot do better than report the last
                 * known RC6 value.
                 */
 -              if (kdev->power.runtime_status == RPM_SUSPENDED) {
 -                      if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
 -                              i915->pmu.suspended_jiffies_last =
 -                                                kdev->power.suspended_jiffies;
 +              if (pm_runtime_status_suspended(kdev)) {
 +                      val = pm_runtime_suspended_time(kdev);
  
 -                      val = kdev->power.suspended_jiffies -
 -                            i915->pmu.suspended_jiffies_last;
 -                      val += jiffies - kdev->power.accounting_timestamp;
 +                      if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
 +                              i915->pmu.suspended_time_last = val;
  
 -                      val = jiffies_to_nsecs(val);
 +                      val -= i915->pmu.suspended_time_last;
                        val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
  
                        i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
                        val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
                }
  
 -              spin_unlock(&kdev->power.lock);
                spin_unlock_irqrestore(&i915->pmu.lock, flags);
        }
  
@@@ -595,7 -599,8 +595,8 @@@ static void i915_pmu_enable(struct perf
         * Update the bitmask of enabled events and increment
         * the event reference counter.
         */
-       GEM_BUG_ON(bit >= I915_PMU_MASK_BITS);
+       BUILD_BUG_ON(ARRAY_SIZE(i915->pmu.enable_count) != I915_PMU_MASK_BITS);
+       GEM_BUG_ON(bit >= ARRAY_SIZE(i915->pmu.enable_count));
        GEM_BUG_ON(i915->pmu.enable_count[bit] == ~0);
        i915->pmu.enable |= BIT_ULL(bit);
        i915->pmu.enable_count[bit]++;
                engine = intel_engine_lookup_user(i915,
                                                  engine_event_class(event),
                                                  engine_event_instance(event));
-               GEM_BUG_ON(!engine);
-               engine->pmu.enable |= BIT(sample);
  
-               GEM_BUG_ON(sample >= I915_PMU_SAMPLE_BITS);
+               BUILD_BUG_ON(ARRAY_SIZE(engine->pmu.enable_count) !=
+                            I915_ENGINE_SAMPLE_COUNT);
+               BUILD_BUG_ON(ARRAY_SIZE(engine->pmu.sample) !=
+                            I915_ENGINE_SAMPLE_COUNT);
+               GEM_BUG_ON(sample >= ARRAY_SIZE(engine->pmu.enable_count));
+               GEM_BUG_ON(sample >= ARRAY_SIZE(engine->pmu.sample));
                GEM_BUG_ON(engine->pmu.enable_count[sample] == ~0);
+               engine->pmu.enable |= BIT(sample);
                engine->pmu.enable_count[sample]++;
        }
  
@@@ -650,9 -660,11 +656,11 @@@ static void i915_pmu_disable(struct per
                engine = intel_engine_lookup_user(i915,
                                                  engine_event_class(event),
                                                  engine_event_instance(event));
-               GEM_BUG_ON(!engine);
-               GEM_BUG_ON(sample >= I915_PMU_SAMPLE_BITS);
+               GEM_BUG_ON(sample >= ARRAY_SIZE(engine->pmu.enable_count));
+               GEM_BUG_ON(sample >= ARRAY_SIZE(engine->pmu.sample));
                GEM_BUG_ON(engine->pmu.enable_count[sample] == 0);
                /*
                 * Decrement the reference count and clear the enabled
                 * bitmask when the last listener on an event goes away.
                        engine->pmu.enable &= ~BIT(sample);
        }
  
-       GEM_BUG_ON(bit >= I915_PMU_MASK_BITS);
+       GEM_BUG_ON(bit >= ARRAY_SIZE(i915->pmu.enable_count));
        GEM_BUG_ON(i915->pmu.enable_count[bit] == 0);
        /*
         * Decrement the reference count and clear the enabled
@@@ -31,6 -31,8 +31,8 @@@ enum 
        ((1 << I915_PMU_SAMPLE_BITS) + \
         (I915_PMU_LAST + 1 - __I915_PMU_OTHER(0)))
  
+ #define I915_ENGINE_SAMPLE_COUNT (I915_SAMPLE_SEMA + 1)
  struct i915_pmu_sample {
        u64 cur;
  };
@@@ -95,9 -97,9 +97,9 @@@ struct i915_pmu 
         */
        struct i915_pmu_sample sample[__I915_NUM_PMU_SAMPLERS];
        /**
 -       * @suspended_jiffies_last: Cached suspend time from PM core.
 +       * @suspended_time_last: Cached suspend time from PM core.
         */
 -      unsigned long suspended_jiffies_last;
 +      u64 suspended_time_last;
        /**
         * @i915_attr: Memory block holding device attributes.
         */
@@@ -35,8 -35,8 +35,8 @@@
  #include <drm/drm_atomic.h>
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_dp_helper.h>
 -#include <drm/drm_crtc_helper.h>
  #include <drm/drm_plane_helper.h>
 +#include <drm/drm_probe_helper.h>
  #include <drm/drm_rect.h>
  #include <drm/drm_atomic_uapi.h>
  #include <linux/intel-iommu.h>
@@@ -1805,7 -1805,7 +1805,7 @@@ static void intel_enable_pipe(const str
         * a plane.  On ILK+ the pipe PLLs are integrated, so we don't
         * need the check.
         */
-       if (HAS_GMCH_DISPLAY(dev_priv)) {
+       if (HAS_GMCH(dev_priv)) {
                if (intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI))
                        assert_dsi_pll_enabled(dev_priv);
                else
@@@ -2094,7 -2094,7 +2094,7 @@@ intel_pin_and_fence_fb_obj(struct drm_f
         * complicated than this. For example, Cherryview appears quite
         * happy to scanout from anywhere within its global aperture.
         */
-       if (HAS_GMCH_DISPLAY(dev_priv))
+       if (HAS_GMCH(dev_priv))
                pinctl |= PIN_MAPPABLE;
  
        vma = i915_gem_object_pin_to_display_plane(obj,
@@@ -3195,7 -3195,7 +3195,7 @@@ i9xx_plane_max_stride(struct intel_plan
  {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  
-       if (!HAS_GMCH_DISPLAY(dev_priv)) {
+       if (!HAS_GMCH(dev_priv)) {
                return 32*1024;
        } else if (INTEL_GEN(dev_priv) >= 4) {
                if (modifier == I915_FORMAT_MOD_X_TILED)
        }
  }
  
+ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
+ {
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       u32 dspcntr = 0;
+       dspcntr |= DISPPLANE_GAMMA_ENABLE;
+       if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+               dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
+       if (INTEL_GEN(dev_priv) < 5)
+               dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
+       return dspcntr;
+ }
  static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
                          const struct intel_plane_state *plane_state)
  {
        struct drm_i915_private *dev_priv =
                to_i915(plane_state->base.plane->dev);
-       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        const struct drm_framebuffer *fb = plane_state->base.fb;
        unsigned int rotation = plane_state->base.rotation;
        u32 dspcntr;
  
-       dspcntr = DISPLAY_PLANE_ENABLE | DISPPLANE_GAMMA_ENABLE;
+       dspcntr = DISPLAY_PLANE_ENABLE;
  
        if (IS_G4X(dev_priv) || IS_GEN(dev_priv, 5) ||
            IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
                dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
  
-       if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-               dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
-       if (INTEL_GEN(dev_priv) < 5)
-               dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
        switch (fb->format->format) {
        case DRM_FORMAT_C8:
                dspcntr |= DISPPLANE_8BPP;
@@@ -3364,11 -3374,13 +3374,13 @@@ static void i9xx_update_plane(struct in
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
        u32 linear_offset;
-       u32 dspcntr = plane_state->ctl;
        int x = plane_state->color_plane[0].x;
        int y = plane_state->color_plane[0].y;
        unsigned long irqflags;
        u32 dspaddr_offset;
+       u32 dspcntr;
+       dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
  
        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  
@@@ -3428,10 -3440,23 +3440,23 @@@ static void i9xx_disable_plane(struct i
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
        unsigned long irqflags;
+       u32 dspcntr;
+       /*
+        * DSPCNTR pipe gamma enable on g4x+ and pipe csc
+        * enable on ilk+ affect the pipe bottom color as
+        * well, so we must configure them even if the plane
+        * is disabled.
+        *
+        * On pre-g4x there is no way to gamma correct the
+        * pipe bottom color but we'll keep on doing this
+        * anyway.
+        */
+       dspcntr = i9xx_plane_ctl_crtc(crtc_state);
  
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  
-       I915_WRITE_FW(DSPCNTR(i9xx_plane), 0);
+       I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
        if (INTEL_GEN(dev_priv) >= 4)
                I915_WRITE_FW(DSPSURF(i9xx_plane), 0);
        else
@@@ -3668,6 -3693,20 +3693,20 @@@ static u32 cnl_plane_ctl_flip(unsigned 
        return 0;
  }
  
+ u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
+ {
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+       u32 plane_ctl = 0;
+       if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+               return plane_ctl;
+       plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
+       plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
+       return plane_ctl;
+ }
  u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
                  const struct intel_plane_state *plane_state)
  {
  
        if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) {
                plane_ctl |= skl_plane_ctl_alpha(plane_state);
-               plane_ctl |=
-                       PLANE_CTL_PIPE_GAMMA_ENABLE |
-                       PLANE_CTL_PIPE_CSC_ENABLE |
-                       PLANE_CTL_PLANE_GAMMA_DISABLE;
+               plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
  
                if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
                        plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
        return plane_ctl;
  }
  
+ u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
+ {
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+       u32 plane_color_ctl = 0;
+       if (INTEL_GEN(dev_priv) >= 11)
+               return plane_color_ctl;
+       plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
+       plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
+       return plane_color_ctl;
+ }
  u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
                        const struct intel_plane_state *plane_state)
  {
-       struct drm_i915_private *dev_priv =
-               to_i915(plane_state->base.plane->dev);
        const struct drm_framebuffer *fb = plane_state->base.fb;
        struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
        u32 plane_color_ctl = 0;
  
-       if (INTEL_GEN(dev_priv) < 11) {
-               plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
-               plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
-       }
        plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
        plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
  
@@@ -3771,7 -3815,7 +3815,7 @@@ __intel_display_resume(struct drm_devic
        }
  
        /* ignore any reset values/BIOS leftovers in the WM registers */
-       if (!HAS_GMCH_DISPLAY(to_i915(dev)))
+       if (!HAS_GMCH(to_i915(dev)))
                to_intel_atomic_state(state)->skip_intermediate_wm = true;
  
        ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
@@@ -3896,6 -3940,30 +3940,30 @@@ unlock
        clear_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
  }
  
+ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
+ {
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
+       u32 tmp;
+       tmp = I915_READ(PIPE_CHICKEN(pipe));
+       /*
+        * Display WA #1153: icl
+        * enable hardware to bypass the alpha math
+        * and rounding for per-pixel values 00 and 0xff
+        */
+       tmp |= PER_PIXEL_ALPHA_BYPASS_EN;
+       /*
+        * W/A for underruns with linear/X-tiled with
+        * WM1+ disabled.
+        */
+       tmp |= PM_FILL_MAINTAIN_DBUF_FULLNESS;
+       I915_WRITE(PIPE_CHICKEN(pipe), tmp);
+ }
  static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_state,
                                     const struct intel_crtc_state *new_crtc_state)
  {
                I915_WRITE(SKL_BOTTOM_COLOR(crtc->pipe),
                           SKL_BOTTOM_COLOR_GAMMA_ENABLE |
                           SKL_BOTTOM_COLOR_CSC_ENABLE);
+       if (INTEL_GEN(dev_priv) >= 11)
+               icl_set_pipe_chicken(crtc);
  }
  
  static void intel_fdi_normal_train(struct intel_crtc *crtc)
@@@ -5294,7 -5365,7 +5365,7 @@@ intel_pre_disable_primary_noatomic(stru
         * event which is after the vblank start event, so we need to have a
         * wait-for-vblank between disabling the plane and the pipe.
         */
-       if (HAS_GMCH_DISPLAY(dev_priv) &&
+       if (HAS_GMCH(dev_priv) &&
            intel_set_memory_cxsr(dev_priv, false))
                intel_wait_for_vblank(dev_priv, pipe);
  }
  static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_state,
                                       const struct intel_crtc_state *new_crtc_state)
  {
+       struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        if (!old_crtc_state->ips_enabled)
                return false;
  
        if (needs_modeset(&new_crtc_state->base))
                return true;
  
+       /*
+        * Workaround : Do not read or write the pipe palette/gamma data while
+        * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+        *
+        * Disable IPS before we program the LUT.
+        */
+       if (IS_HASWELL(dev_priv) &&
+           (new_crtc_state->base.color_mgmt_changed ||
+            new_crtc_state->update_pipe) &&
+           new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
+               return true;
        return !new_crtc_state->ips_enabled;
  }
  
  static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_state,
                                       const struct intel_crtc_state *new_crtc_state)
  {
+       struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        if (!new_crtc_state->ips_enabled)
                return false;
  
        if (needs_modeset(&new_crtc_state->base))
                return true;
  
+       /*
+        * Workaround : Do not read or write the pipe palette/gamma data while
+        * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+        *
+        * Re-enable IPS after the LUT has been programmed.
+        */
+       if (IS_HASWELL(dev_priv) &&
+           (new_crtc_state->base.color_mgmt_changed ||
+            new_crtc_state->update_pipe) &&
+           new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
+               return true;
        /*
         * We can't read out IPS on broadwell, assume the worst and
         * forcibly enable IPS on the first fastset.
@@@ -5431,7 -5532,7 +5532,7 @@@ static void intel_pre_plane_update(stru
         * event which is after the vblank start event, so we need to have a
         * wait-for-vblank between disabling the plane and the pipe.
         */
-       if (HAS_GMCH_DISPLAY(dev_priv) && old_crtc_state->base.active &&
+       if (HAS_GMCH(dev_priv) && old_crtc_state->base.active &&
            pipe_config->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
                intel_wait_for_vblank(dev_priv, crtc->pipe);
  
@@@ -5708,6 -5809,7 +5809,7 @@@ static void ironlake_crtc_enable(struc
         * clocks enabled
         */
        intel_color_load_luts(pipe_config);
+       intel_color_commit(pipe_config);
  
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
@@@ -5782,7 -5884,6 +5884,6 @@@ static void haswell_crtc_enable(struct 
        struct intel_atomic_state *old_intel_state =
                to_intel_atomic_state(old_state);
        bool psl_clkgate_wa;
-       u32 pipe_chicken;
  
        if (WARN_ON(intel_crtc->active))
                return;
  
        haswell_set_pipemisc(pipe_config);
  
-       intel_color_set_csc(pipe_config);
        intel_crtc->active = true;
  
        /* Display WA #1180: WaDisableScalarClockGating: glk, cnl */
         * clocks enabled
         */
        intel_color_load_luts(pipe_config);
+       intel_color_commit(pipe_config);
  
-       /*
-        * Display WA #1153: enable hardware to bypass the alpha math
-        * and rounding for per-pixel values 00 and 0xff
-        */
-       if (INTEL_GEN(dev_priv) >= 11) {
-               pipe_chicken = I915_READ(PIPE_CHICKEN(pipe));
-               if (!(pipe_chicken & PER_PIXEL_ALPHA_BYPASS_EN))
-                       I915_WRITE_FW(PIPE_CHICKEN(pipe),
-                                     pipe_chicken | PER_PIXEL_ALPHA_BYPASS_EN);
-       }
+       if (INTEL_GEN(dev_priv) >= 11)
+               icl_set_pipe_chicken(intel_crtc);
  
        intel_ddi_set_pipe_settings(pipe_config);
        if (!transcoder_is_dsi(cpu_transcoder))
@@@ -6183,8 -6275,6 +6275,6 @@@ static void valleyview_crtc_enable(stru
  
        i9xx_set_pipeconf(pipe_config);
  
-       intel_color_set_csc(pipe_config);
        intel_crtc->active = true;
  
        intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        i9xx_pfit_enable(pipe_config);
  
        intel_color_load_luts(pipe_config);
+       intel_color_commit(pipe_config);
  
        dev_priv->display.initial_watermarks(old_intel_state,
                                             pipe_config);
@@@ -6260,6 -6351,7 +6351,7 @@@ static void i9xx_crtc_enable(struct int
        i9xx_pfit_enable(pipe_config);
  
        intel_color_load_luts(pipe_config);
+       intel_color_commit(pipe_config);
  
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state,
@@@ -6705,7 -6797,7 +6797,7 @@@ static void intel_crtc_compute_pixel_ra
  {
        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
  
-       if (HAS_GMCH_DISPLAY(dev_priv))
+       if (HAS_GMCH(dev_priv))
                /* FIXME calculate proper pipe pixel rate for GMCH pfit */
                crtc_state->pixel_rate =
                        crtc_state->base.adjusted_mode.crtc_clock;
@@@ -9814,7 -9906,7 +9906,7 @@@ static u32 intel_cursor_base(const stru
        base += plane_state->color_plane[0].offset;
  
        /* ILK+ do this automagically */
-       if (HAS_GMCH_DISPLAY(dev_priv) &&
+       if (HAS_GMCH(dev_priv) &&
            plane_state->base.rotation & DRM_MODE_ROTATE_180)
                base += (plane_state->base.crtc_h *
                         plane_state->base.crtc_w - 1) * fb->format->cpp[0];
@@@ -9927,11 -10019,15 +10019,15 @@@ i845_cursor_max_stride(struct intel_pla
        return 2048;
  }
  
+ static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
+ {
+       return CURSOR_GAMMA_ENABLE;
+ }
  static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
                           const struct intel_plane_state *plane_state)
  {
        return CURSOR_ENABLE |
-               CURSOR_GAMMA_ENABLE |
                CURSOR_FORMAT_ARGB |
                CURSOR_STRIDE(plane_state->color_plane[0].stride);
  }
@@@ -10001,7 -10097,9 +10097,9 @@@ static void i845_update_cursor(struct i
                unsigned int width = plane_state->base.crtc_w;
                unsigned int height = plane_state->base.crtc_h;
  
-               cntl = plane_state->ctl;
+               cntl = plane_state->ctl |
+                       i845_cursor_ctl_crtc(crtc_state);
                size = (height << 12) | width;
  
                base = intel_cursor_base(plane_state);
@@@ -10068,27 -10166,36 +10166,36 @@@ i9xx_cursor_max_stride(struct intel_pla
        return plane->base.dev->mode_config.cursor_width * 4;
  }
  
- static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
-                          const struct intel_plane_state *plane_state)
+ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
  {
-       struct drm_i915_private *dev_priv =
-               to_i915(plane_state->base.plane->dev);
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 cntl = 0;
  
-       if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
-               cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
+       if (INTEL_GEN(dev_priv) >= 11)
+               return cntl;
  
-       if (INTEL_GEN(dev_priv) <= 10) {
-               cntl |= MCURSOR_GAMMA_ENABLE;
+       cntl |= MCURSOR_GAMMA_ENABLE;
  
-               if (HAS_DDI(dev_priv))
-                       cntl |= MCURSOR_PIPE_CSC_ENABLE;
-       }
+       if (HAS_DDI(dev_priv))
+               cntl |= MCURSOR_PIPE_CSC_ENABLE;
  
        if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
                cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
  
+       return cntl;
+ }
+ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
+                          const struct intel_plane_state *plane_state)
+ {
+       struct drm_i915_private *dev_priv =
+               to_i915(plane_state->base.plane->dev);
+       u32 cntl = 0;
+       if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
+               cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
        switch (plane_state->base.crtc_w) {
        case 64:
                cntl |= MCURSOR_MODE_64_ARGB_AX;
@@@ -10213,7 -10320,8 +10320,8 @@@ static void i9xx_update_cursor(struct i
        unsigned long irqflags;
  
        if (plane_state && plane_state->base.visible) {
-               cntl = plane_state->ctl;
+               cntl = plane_state->ctl |
+                       i9xx_cursor_ctl_crtc(crtc_state);
  
                if (plane_state->base.crtc_h != plane_state->base.crtc_w)
                        fbc_ctl = CUR_FBC_CTL_EN | (plane_state->base.crtc_h - 1);
@@@ -11045,7 -11153,8 +11153,8 @@@ static int intel_crtc_atomic_check(stru
        int ret;
        bool mode_changed = needs_modeset(crtc_state);
  
-       if (mode_changed && !crtc_state->active)
+       if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
+           mode_changed && !crtc_state->active)
                pipe_config->update_wm_post = true;
  
        if (mode_changed && crtc_state->enable &&
                        return ret;
        }
  
-       if (crtc_state->color_mgmt_changed) {
+       if (mode_changed || crtc_state->color_mgmt_changed) {
                ret = intel_color_check(pipe_config);
                if (ret)
                        return ret;
@@@ -11356,7 -11465,7 +11465,7 @@@ static void intel_dump_pipe_config(stru
                              pipe_config->scaler_state.scaler_users,
                              pipe_config->scaler_state.scaler_id);
  
-       if (HAS_GMCH_DISPLAY(dev_priv))
+       if (HAS_GMCH(dev_priv))
                DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
                              pipe_config->gmch_pfit.control,
                              pipe_config->gmch_pfit.pgm_ratios,
@@@ -11468,44 -11577,38 +11577,38 @@@ static bool check_digital_port_conflict
        return ret;
  }
  
- static void
+ static int
  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
  {
        struct drm_i915_private *dev_priv =
                to_i915(crtc_state->base.crtc->dev);
-       struct intel_crtc_scaler_state scaler_state;
-       struct intel_dpll_hw_state dpll_hw_state;
-       struct intel_shared_dpll *shared_dpll;
-       struct intel_crtc_wm_state wm_state;
-       bool force_thru, ips_force_disable;
+       struct intel_crtc_state *saved_state;
+       saved_state = kzalloc(sizeof(*saved_state), GFP_KERNEL);
+       if (!saved_state)
+               return -ENOMEM;
  
        /* FIXME: before the switch to atomic started, a new pipe_config was
         * kzalloc'd. Code that depends on any field being zero should be
         * fixed, so that the crtc_state can be safely duplicated. For now,
         * only fields that are know to not cause problems are preserved. */
  
-       scaler_state = crtc_state->scaler_state;
-       shared_dpll = crtc_state->shared_dpll;
-       dpll_hw_state = crtc_state->dpll_hw_state;
-       force_thru = crtc_state->pch_pfit.force_thru;
-       ips_force_disable = crtc_state->ips_force_disable;
+       saved_state->scaler_state = crtc_state->scaler_state;
+       saved_state->shared_dpll = crtc_state->shared_dpll;
+       saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
+       saved_state->pch_pfit.force_thru = crtc_state->pch_pfit.force_thru;
+       saved_state->ips_force_disable = crtc_state->ips_force_disable;
        if (IS_G4X(dev_priv) ||
            IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-               wm_state = crtc_state->wm;
+               saved_state->wm = crtc_state->wm;
  
        /* Keep base drm_crtc_state intact, only clear our extended struct */
        BUILD_BUG_ON(offsetof(struct intel_crtc_state, base));
-       memset(&crtc_state->base + 1, 0,
+       memcpy(&crtc_state->base + 1, &saved_state->base + 1,
               sizeof(*crtc_state) - sizeof(crtc_state->base));
  
-       crtc_state->scaler_state = scaler_state;
-       crtc_state->shared_dpll = shared_dpll;
-       crtc_state->dpll_hw_state = dpll_hw_state;
-       crtc_state->pch_pfit.force_thru = force_thru;
-       crtc_state->ips_force_disable = ips_force_disable;
-       if (IS_G4X(dev_priv) ||
-           IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-               crtc_state->wm = wm_state;
+       kfree(saved_state);
+       return 0;
  }
  
  static int
@@@ -11520,7 -11623,9 +11623,9 @@@ intel_modeset_pipe_config(struct drm_cr
        int i;
        bool retry = true;
  
-       clear_intel_crtc_state(pipe_config);
+       ret = clear_intel_crtc_state(pipe_config);
+       if (ret)
+               return ret;
  
        pipe_config->cpu_transcoder =
                (enum transcoder) to_intel_crtc(crtc)->pipe;
@@@ -13096,7 -13201,7 +13201,7 @@@ static void intel_atomic_commit_tail(st
  
                        /* FIXME unify this for all platforms */
                        if (!new_crtc_state->active &&
-                           !HAS_GMCH_DISPLAY(dev_priv) &&
+                           !HAS_GMCH(dev_priv) &&
                            dev_priv->display.initial_watermarks)
                                dev_priv->display.initial_watermarks(intel_state,
                                                                     new_intel_crtc_state);
         */
        drm_atomic_helper_wait_for_flip_done(dev, state);
  
+       for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+               new_intel_crtc_state = to_intel_crtc_state(new_crtc_state);
+               if (new_crtc_state->active &&
+                   !needs_modeset(new_crtc_state) &&
+                   (new_intel_crtc_state->base.color_mgmt_changed ||
+                    new_intel_crtc_state->update_pipe))
+                       intel_color_load_luts(new_intel_crtc_state);
+       }
        /*
         * Now that the vblank has passed, we can go ahead and program the
         * optimal watermarks on platforms that need two-step watermark
@@@ -13665,19 -13780,16 +13780,16 @@@ static void intel_begin_crtc_commit(str
                intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc);
        bool modeset = needs_modeset(&intel_cstate->base);
  
-       if (!modeset &&
-           (intel_cstate->base.color_mgmt_changed ||
-            intel_cstate->update_pipe)) {
-               intel_color_set_csc(intel_cstate);
-               intel_color_load_luts(intel_cstate);
-       }
        /* Perform vblank evasion around commit operation */
        intel_pipe_update_start(intel_cstate);
  
        if (modeset)
                goto out;
  
+       if (intel_cstate->base.color_mgmt_changed ||
+           intel_cstate->update_pipe)
+               intel_color_commit(intel_cstate);
        if (intel_cstate->update_pipe)
                intel_update_pipe_config(old_intel_cstate, intel_cstate);
        else if (INTEL_GEN(dev_priv) >= 9)
@@@ -15074,7 -15186,7 +15186,7 @@@ retry
         * intermediate watermarks (since we don't trust the current
         * watermarks).
         */
-       if (!HAS_GMCH_DISPLAY(dev_priv))
+       if (!HAS_GMCH(dev_priv))
                intel_state->skip_intermediate_wm = true;
  
        ret = intel_atomic_check(dev, state);
@@@ -15315,7 -15427,7 +15427,7 @@@ int intel_modeset_init(struct drm_devic
         * Note that we need to do this after reconstructing the BIOS fb's
         * since the watermark calculation done here will use pstate->fb.
         */
-       if (!HAS_GMCH_DISPLAY(dev_priv))
+       if (!HAS_GMCH(dev_priv))
                sanitize_watermarks(dev);
  
        /*
@@@ -15524,7 -15636,7 +15636,7 @@@ static void intel_sanitize_crtc(struct 
        if (crtc_state->base.active && !intel_crtc_has_encoders(crtc))
                intel_crtc_disable_noatomic(&crtc->base, ctx);
  
-       if (crtc_state->base.active || HAS_GMCH_DISPLAY(dev_priv)) {
+       if (crtc_state->base.active || HAS_GMCH(dev_priv)) {
                /*
                 * We start out with underrun reporting disabled to avoid races.
                 * For correct bookkeeping mark this on active crtcs.
@@@ -16271,7 -16383,7 +16383,7 @@@ intel_display_capture_error_state(struc
  
                error->pipe[i].source = I915_READ(PIPESRC(i));
  
-               if (HAS_GMCH_DISPLAY(dev_priv))
+               if (HAS_GMCH(dev_priv))
                        error->pipe[i].stat = I915_READ(PIPESTAT(i));
        }
  
  #include <asm/byteorder.h>
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_crtc.h>
 -#include <drm/drm_crtc_helper.h>
  #include <drm/drm_dp_helper.h>
  #include <drm/drm_edid.h>
  #include <drm/drm_hdcp.h>
 +#include <drm/drm_probe_helper.h>
  #include "intel_drv.h"
  #include <drm/i915_drm.h>
  #include "i915_drv.h"
@@@ -1061,6 -1061,10 +1061,10 @@@ intel_dp_aux_wait_done(struct intel_dp 
  #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
        done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
                                  msecs_to_jiffies_timeout(10));
+       /* just trace the final value */
+       trace_i915_reg_rw(false, ch_ctl, status, sizeof(status), true);
        if (!done)
                DRM_ERROR("dp aux hw did not signal timeout!\n");
  #undef C
@@@ -1227,6 -1231,8 +1231,8 @@@ intel_dp_aux_xfer(struct intel_dp *inte
                        break;
                msleep(1);
        }
+       /* just trace the final value */
+       trace_i915_reg_rw(false, ch_ctl, status, sizeof(status), true);
  
        if (try == 3) {
                static u32 last_status = -1;
@@@ -2141,7 -2147,7 +2147,7 @@@ intel_dp_compute_config(struct intel_en
                                return ret;
                }
  
-               if (HAS_GMCH_DISPLAY(dev_priv))
+               if (HAS_GMCH(dev_priv))
                        intel_gmch_panel_fitting(intel_crtc, pipe_config,
                                                 conn_state->scaling_mode);
                else
        if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return -EINVAL;
  
-       if (HAS_GMCH_DISPLAY(dev_priv) &&
+       if (HAS_GMCH(dev_priv) &&
            adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
                return -EINVAL;
  
@@@ -4608,12 -4614,10 +4614,10 @@@ go_again
  
                        return ret;
                } else {
-                       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
                        DRM_DEBUG_KMS("failed to get ESI - device may have failed\n");
                        intel_dp->is_mst = false;
-                       drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
-                       /* send a hotplug event */
-                       drm_kms_helper_hotplug_event(intel_dig_port->base.base.dev);
+                       drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+                                                       intel_dp->is_mst);
                }
        }
        return -EINVAL;
@@@ -5300,7 -5304,7 +5304,7 @@@ bool intel_digital_port_connected(struc
  {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
  
-       if (HAS_GMCH_DISPLAY(dev_priv)) {
+       if (HAS_GMCH(dev_priv)) {
                if (IS_GM45(dev_priv))
                        return gm45_digital_port_connected(encoder);
                else
@@@ -6038,7 -6042,7 +6042,7 @@@ intel_dp_add_properties(struct intel_d
                intel_attach_force_audio_property(connector);
  
        intel_attach_broadcast_rgb_property(connector);
-       if (HAS_GMCH_DISPLAY(dev_priv))
+       if (HAS_GMCH(dev_priv))
                drm_connector_attach_max_bpc_property(connector, 6, 10);
        else if (INTEL_GEN(dev_priv) >= 5)
                drm_connector_attach_max_bpc_property(connector, 6, 12);
                u32 allowed_scalers;
  
                allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN);
-               if (!HAS_GMCH_DISPLAY(dev_priv))
+               if (!HAS_GMCH(dev_priv))
                        allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
  
                drm_connector_attach_scaling_mode_property(connector, allowed_scalers);
@@@ -6919,7 -6923,7 +6923,7 @@@ intel_dp_init_connector(struct intel_di
        drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
        drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
  
-       if (!HAS_GMCH_DISPLAY(dev_priv))
+       if (!HAS_GMCH(dev_priv))
                connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
  
@@@ -7096,7 -7100,10 +7100,10 @@@ void intel_dp_mst_resume(struct drm_i91
                        continue;
  
                ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr);
-               if (ret)
-                       intel_dp_check_mst_status(intel_dp);
+               if (ret) {
+                       intel_dp->is_mst = false;
+                       drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+                                                       false);
+               }
        }
  }
  #include <drm/i915_drm.h>
  #include "i915_drv.h"
  #include <drm/drm_crtc.h>
 -#include <drm/drm_crtc_helper.h>
  #include <drm/drm_encoder.h>
  #include <drm/drm_fb_helper.h>
  #include <drm/drm_dp_dual_mode_helper.h>
  #include <drm/drm_dp_mst_helper.h>
 +#include <drm/drm_probe_helper.h>
  #include <drm/drm_rect.h>
 +#include <drm/drm_vblank.h>
  #include <drm/drm_atomic.h>
  #include <media/cec-notifier.h>
  
@@@ -213,6 -212,16 +213,16 @@@ struct intel_fbdev 
        unsigned long vma_flags;
        async_cookie_t cookie;
        int preferred_bpp;
+       /* Whether or not fbdev hpd processing is temporarily suspended */
+       bool hpd_suspended : 1;
+       /* Set when a hotplug was received while HPD processing was
+        * suspended
+        */
+       bool hpd_waiting : 1;
+       /* Protects hpd_suspended */
+       struct mutex hpd_lock;
  };
  
  struct intel_encoder {
@@@ -1756,9 -1765,10 +1766,10 @@@ static inline u32 intel_plane_ggtt_offs
  
  u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
                        const struct intel_plane_state *plane_state);
+ u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state);
  u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
                  const struct intel_plane_state *plane_state);
- u32 glk_color_ctl(const struct intel_plane_state *plane_state);
+ u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
  u32 skl_plane_stride(const struct intel_plane_state *plane_state,
                     int plane);
  int skl_check_plane_surface(struct intel_plane_state *plane_state);
@@@ -2067,9 -2077,9 +2078,9 @@@ void intel_psr_enable(struct intel_dp *
                      const struct intel_crtc_state *crtc_state);
  void intel_psr_disable(struct intel_dp *intel_dp,
                      const struct intel_crtc_state *old_crtc_state);
int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv,
-                              struct drm_modeset_acquire_ctx *ctx,
                             u64 value);
void intel_psr_update(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state);
int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value);
  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
                          unsigned frontbuffer_bits,
                          enum fb_op_origin origin);
@@@ -2379,8 -2389,8 +2390,8 @@@ int intel_plane_atomic_check_with_state
  /* intel_color.c */
  void intel_color_init(struct intel_crtc *crtc);
  int intel_color_check(struct intel_crtc_state *crtc_state);
- void intel_color_set_csc(struct intel_crtc_state *crtc_state);
- void intel_color_load_luts(struct intel_crtc_state *crtc_state);
+ void intel_color_commit(const struct intel_crtc_state *crtc_state);
+ void intel_color_load_luts(const struct intel_crtc_state *crtc_state);
  
  /* intel_lspcon.c */
  bool lspcon_init(struct intel_digital_port *intel_dig_port);
@@@ -39,8 -39,6 +39,8 @@@
  
  #include <drm/drm_crtc.h>
  #include <drm/drm_fb_helper.h>
 +#include <drm/drm_fourcc.h>
 +
  #include "intel_drv.h"
  #include "intel_frontbuffer.h"
  #include <drm/i915_drm.h>
@@@ -681,6 -679,7 +681,7 @@@ int intel_fbdev_init(struct drm_device 
        if (ifbdev == NULL)
                return -ENOMEM;
  
+       mutex_init(&ifbdev->hpd_lock);
        drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
  
        if (!intel_fbdev_init_bios(dev, ifbdev))
@@@ -754,6 -753,26 +755,26 @@@ void intel_fbdev_fini(struct drm_i915_p
        intel_fbdev_destroy(ifbdev);
  }
  
+ /* Suspends/resumes fbdev processing of incoming HPD events. When resuming HPD
+  * processing, fbdev will perform a full connector reprobe if a hotplug event
+  * was received while HPD was suspended.
+  */
+ static void intel_fbdev_hpd_set_suspend(struct intel_fbdev *ifbdev, int state)
+ {
+       bool send_hpd = false;
+       mutex_lock(&ifbdev->hpd_lock);
+       ifbdev->hpd_suspended = state == FBINFO_STATE_SUSPENDED;
+       send_hpd = !ifbdev->hpd_suspended && ifbdev->hpd_waiting;
+       ifbdev->hpd_waiting = false;
+       mutex_unlock(&ifbdev->hpd_lock);
+       if (send_hpd) {
+               DRM_DEBUG_KMS("Handling delayed fbcon HPD event\n");
+               drm_fb_helper_hotplug_event(&ifbdev->helper);
+       }
+ }
  void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
  {
        struct drm_i915_private *dev_priv = to_i915(dev);
                 */
                if (state != FBINFO_STATE_RUNNING)
                        flush_work(&dev_priv->fbdev_suspend_work);
                console_lock();
        } else {
                /*
  
        drm_fb_helper_set_suspend(&ifbdev->helper, state);
        console_unlock();
+       intel_fbdev_hpd_set_suspend(ifbdev, state);
  }
  
  void intel_fbdev_output_poll_changed(struct drm_device *dev)
  {
        struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
+       bool send_hpd;
  
        if (!ifbdev)
                return;
  
        intel_fbdev_sync(ifbdev);
-       if (ifbdev->vma || ifbdev->helper.deferred_setup)
+       mutex_lock(&ifbdev->hpd_lock);
+       send_hpd = !ifbdev->hpd_suspended;
+       ifbdev->hpd_waiting = true;
+       mutex_unlock(&ifbdev->hpd_lock);
+       if (send_hpd && (ifbdev->vma || ifbdev->helper.deferred_setup))
                drm_fb_helper_hotplug_event(&ifbdev->helper);
  }
  
@@@ -26,8 -26,6 +26,8 @@@
   * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
   */
  #include <drm/i915_drm.h>
 +#include <drm/drm_fourcc.h>
 +
  #include "i915_drv.h"
  #include "i915_reg.h"
  #include "intel_drv.h"
@@@ -186,7 -184,7 +186,7 @@@ struct intel_overlay 
        struct overlay_registers __iomem *regs;
        u32 flip_addr;
        /* flip handling */
-       struct i915_gem_active last_flip;
+       struct i915_active_request last_flip;
  };
  
  static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
  
  static void intel_overlay_submit_request(struct intel_overlay *overlay,
                                         struct i915_request *rq,
-                                        i915_gem_retire_fn retire)
+                                        i915_active_retire_fn retire)
  {
-       GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip,
-                                       &overlay->i915->drm.struct_mutex));
-       i915_gem_active_set_retire_fn(&overlay->last_flip, retire,
-                                     &overlay->i915->drm.struct_mutex);
-       i915_gem_active_set(&overlay->last_flip, rq);
+       GEM_BUG_ON(i915_active_request_peek(&overlay->last_flip,
+                                           &overlay->i915->drm.struct_mutex));
+       i915_active_request_set_retire_fn(&overlay->last_flip, retire,
+                                         &overlay->i915->drm.struct_mutex);
+       __i915_active_request_set(&overlay->last_flip, rq);
        i915_request_add(rq);
  }
  
  static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
                                         struct i915_request *rq,
-                                        i915_gem_retire_fn retire)
+                                        i915_active_retire_fn retire)
  {
        intel_overlay_submit_request(overlay, rq, retire);
-       return i915_gem_active_retire(&overlay->last_flip,
-                                     &overlay->i915->drm.struct_mutex);
+       return i915_active_request_retire(&overlay->last_flip,
+                                         &overlay->i915->drm.struct_mutex);
  }
  
  static struct i915_request *alloc_request(struct intel_overlay *overlay)
@@@ -351,8 -349,9 +351,9 @@@ static void intel_overlay_release_old_v
        i915_vma_put(vma);
  }
  
- static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
-                                              struct i915_request *rq)
+ static void
+ intel_overlay_release_old_vid_tail(struct i915_active_request *active,
+                                  struct i915_request *rq)
  {
        struct intel_overlay *overlay =
                container_of(active, typeof(*overlay), last_flip);
        intel_overlay_release_old_vma(overlay);
  }
  
- static void intel_overlay_off_tail(struct i915_gem_active *active,
+ static void intel_overlay_off_tail(struct i915_active_request *active,
                                   struct i915_request *rq)
  {
        struct intel_overlay *overlay =
@@@ -423,8 -422,8 +424,8 @@@ static int intel_overlay_off(struct int
   * We have to be careful not to repeat work forever an make forward progess. */
  static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
  {
-       return i915_gem_active_retire(&overlay->last_flip,
-                                     &overlay->i915->drm.struct_mutex);
+       return i915_active_request_retire(&overlay->last_flip,
+                                         &overlay->i915->drm.struct_mutex);
  }
  
  /* Wait for pending overlay flip and release old frame.
@@@ -1357,7 -1356,7 +1358,7 @@@ void intel_overlay_setup(struct drm_i91
        overlay->contrast = 75;
        overlay->saturation = 146;
  
-       init_request_active(&overlay->last_flip, NULL);
+       INIT_ACTIVE_REQUEST(&overlay->last_flip);
  
        mutex_lock(&dev_priv->drm.struct_mutex);