Merge tag 'drm-intel-next-2018-04-13' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Fri, 4 May 2018 00:31:10 +0000 (10:31 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 4 May 2018 00:32:21 +0000 (10:32 +1000)
First drm/i915 feature batch heading for v4.18:

- drm-next backmerge to fix build (Rodrigo)
- GPU documentation improvements (Kevin)
- GuC and HuC refactoring, host/GuC communication, logging, fixes, and more
  (mostly Michal and Michał, also Jackie, Michel and Piotr)
- PSR and PSR2 enabling and fixes (DK, José, Rodrigo and Chris)
- Selftest updates (Chris, Daniele)
- DPLL management refactoring (Lucas)
- DP MST fixes (Lyude and DK)
- Watermark refactoring and changes to support NV12 (Mahesh)
- NV12 prep work (Chandra)
- Icelake Combo PHY enablers (Manasi)
- Perf OA refactoring and ICL enabling (Lionel)
- ICL enabling (Oscar, Paulo, Nabendu, Mika, Kelvin, Michel)
- Workarounds refactoring (Oscar)
- HDCP fixes and improvements (Ramalingam, Radhakrishna)
- Power management fixes (Imre)
- Various display fixes (Maarten, Ville, Vidya, Jani, Gaurav)
- debugfs for FIFO underrun clearing (Maarten)
- Execlist improvements (Chris)
- Reset improvements (Chris)
- Plenty of things here and there I overlooked and/or didn't understand... (Everyone)

Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87lgd2cze8.fsf@intel.com
1  2 
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbdev.c

@@@ -377,9 -377,9 +377,9 @@@ static int i915_getparam_ioctl(struct d
                value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
                break;
        case I915_PARAM_HUC_STATUS:
-               intel_runtime_pm_get(dev_priv);
-               value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
-               intel_runtime_pm_put(dev_priv);
+               value = intel_huc_check_status(&dev_priv->huc);
+               if (value < 0)
+                       return value;
                break;
        case I915_PARAM_MMAP_GTT_VERSION:
                /* Though we've started our numbering from 1, and so class all
  
  static int i915_get_bridge_dev(struct drm_i915_private *dev_priv)
  {
 -      dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
 +      int domain = pci_domain_nr(dev_priv->drm.pdev->bus);
 +
 +      dev_priv->bridge_dev =
 +              pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(0, 0));
        if (!dev_priv->bridge_dev) {
                DRM_ERROR("bridge device not found\n");
                return -1;
@@@ -695,11 -692,9 +695,9 @@@ static int i915_load_modeset_init(struc
        if (ret)
                goto cleanup_irq;
  
-       intel_uc_init_fw(dev_priv);
        ret = i915_gem_init(dev_priv);
        if (ret)
-               goto cleanup_uc;
+               goto cleanup_irq;
  
        intel_setup_overlay(dev_priv);
  
@@@ -719,8 -714,6 +717,6 @@@ cleanup_gem
        if (i915_gem_suspend(dev_priv))
                DRM_ERROR("failed to idle hardware; continuing to unload!\n");
        i915_gem_fini(dev_priv);
- cleanup_uc:
-       intel_uc_fini_fw(dev_priv);
  cleanup_irq:
        drm_irq_uninstall(dev);
        intel_teardown_gmbus(dev_priv);
@@@ -922,16 -915,21 +918,21 @@@ static int i915_driver_init_early(struc
        mutex_init(&dev_priv->wm.wm_mutex);
        mutex_init(&dev_priv->pps_mutex);
  
-       intel_uc_init_early(dev_priv);
        i915_memcpy_init_early(dev_priv);
  
        ret = i915_workqueues_init(dev_priv);
        if (ret < 0)
                goto err_engines;
  
+       ret = i915_gem_init_early(dev_priv);
+       if (ret < 0)
+               goto err_workqueues;
        /* This must be called before any calls to HAS_PCH_* */
        intel_detect_pch(dev_priv);
  
+       intel_wopcm_init_early(&dev_priv->wopcm);
+       intel_uc_init_early(dev_priv);
        intel_pm_setup(dev_priv);
        intel_init_dpio(dev_priv);
        intel_power_domains_init(dev_priv);
        intel_init_display_hooks(dev_priv);
        intel_init_clock_gating_hooks(dev_priv);
        intel_init_audio_hooks(dev_priv);
-       ret = i915_gem_load_init(dev_priv);
-       if (ret < 0)
-               goto err_irq;
        intel_display_crc_init(dev_priv);
  
        intel_detect_preproduction_hw(dev_priv);
  
        return 0;
  
- err_irq:
-       intel_irq_fini(dev_priv);
+ err_workqueues:
        i915_workqueues_cleanup(dev_priv);
  err_engines:
        i915_engines_cleanup(dev_priv);
   */
  static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
  {
-       i915_gem_load_cleanup(dev_priv);
        intel_irq_fini(dev_priv);
+       intel_uc_cleanup_early(dev_priv);
+       i915_gem_cleanup_early(dev_priv);
        i915_workqueues_cleanup(dev_priv);
        i915_engines_cleanup(dev_priv);
  }
@@@ -1035,6 -1029,10 +1032,10 @@@ static int i915_driver_init_mmio(struc
  
        intel_uncore_init(dev_priv);
  
+       intel_device_info_init_mmio(dev_priv);
+       intel_uncore_prune(dev_priv);
        intel_uc_init_mmio(dev_priv);
  
        ret = intel_engines_init_mmio(dev_priv);
@@@ -1077,8 -1075,6 +1078,6 @@@ static void intel_sanitize_options(stru
                                            i915_modparams.enable_ppgtt);
        DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt);
  
-       intel_uc_sanitize_options(dev_priv);
        intel_gvt_sanitize_options(dev_priv);
  }
  
@@@ -1105,32 -1101,30 +1104,32 @@@ static int i915_driver_init_hw(struct d
  
        ret = i915_ggtt_probe_hw(dev_priv);
        if (ret)
 -              return ret;
 +              goto err_perf;
  
 -      /* WARNING: Apparently we must kick fbdev drivers before vgacon,
 -       * otherwise the vga fbdev driver falls over. */
 +      /*
 +       * WARNING: Apparently we must kick fbdev drivers before vgacon,
 +       * otherwise the vga fbdev driver falls over.
 +       */
        ret = i915_kick_out_firmware_fb(dev_priv);
        if (ret) {
                DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
 -              goto out_ggtt;
 +              goto err_ggtt;
        }
  
        ret = i915_kick_out_vgacon(dev_priv);
        if (ret) {
                DRM_ERROR("failed to remove conflicting VGA console\n");
 -              goto out_ggtt;
 +              goto err_ggtt;
        }
  
        ret = i915_ggtt_init_hw(dev_priv);
        if (ret)
 -              return ret;
 +              goto err_ggtt;
  
        ret = i915_ggtt_enable_hw(dev_priv);
        if (ret) {
                DRM_ERROR("failed to enable GGTT\n");
 -              goto out_ggtt;
 +              goto err_ggtt;
        }
  
        pci_set_master(pdev);
                if (ret) {
                        DRM_ERROR("failed to set DMA mask\n");
  
 -                      goto out_ggtt;
 +                      goto err_ggtt;
                }
        }
  
                if (ret) {
                        DRM_ERROR("failed to set DMA mask\n");
  
 -                      goto out_ggtt;
 +                      goto err_ggtt;
                }
        }
  
  
        ret = intel_gvt_init(dev_priv);
        if (ret)
 -              goto out_ggtt;
 +              goto err_ggtt;
  
        return 0;
  
 -out_ggtt:
 +err_ggtt:
        i915_ggtt_cleanup_hw(dev_priv);
 -
 +err_perf:
 +      i915_perf_fini(dev_priv);
        return ret;
  }
  
@@@ -1244,7 -1237,6 +1243,6 @@@ static void i915_driver_register(struc
        /* Reveal our presence to userspace */
        if (drm_dev_register(dev, 0) == 0) {
                i915_debugfs_register(dev_priv);
-               i915_guc_log_register(dev_priv);
                i915_setup_sysfs(dev_priv);
  
                /* Depends on sysfs having been initialized */
@@@ -1304,7 -1296,6 +1302,6 @@@ static void i915_driver_unregister(stru
        i915_pmu_unregister(dev_priv);
  
        i915_teardown_sysfs(dev_priv);
-       i915_guc_log_unregister(dev_priv);
        drm_dev_unregister(&dev_priv->drm);
  
        i915_gem_shrinker_unregister(dev_priv);
@@@ -1463,7 -1454,6 +1460,6 @@@ void i915_driver_unload(struct drm_devi
        i915_reset_error_state(dev_priv);
  
        i915_gem_fini(dev_priv);
-       intel_uc_fini_fw(dev_priv);
        intel_fbc_cleanup_cfb(dev_priv);
  
        intel_power_domains_fini(dev_priv);
@@@ -1876,7 -1866,8 +1872,8 @@@ static int i915_resume_switcheroo(struc
  /**
   * i915_reset - reset chip after a hang
   * @i915: #drm_i915_private to reset
-  * @flags: Instructions
+  * @stalled_mask: mask of the stalled engines with the guilty requests
+  * @reason: user error message for why we are resetting
   *
   * Reset the chip.  Useful if a hang is detected. Marks the device as wedged
   * on failure.
   *   - re-init interrupt state
   *   - re-init display
   */
- void i915_reset(struct drm_i915_private *i915, unsigned int flags)
+ void i915_reset(struct drm_i915_private *i915,
+               unsigned int stalled_mask,
+               const char *reason)
  {
        struct i915_gpu_error *error = &i915->gpu_error;
        int ret;
        int i;
  
+       GEM_TRACE("flags=%lx\n", error->flags);
        might_sleep();
        lockdep_assert_held(&i915->drm.struct_mutex);
        GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
        if (!i915_gem_unset_wedged(i915))
                goto wakeup;
  
-       if (!(flags & I915_RESET_QUIET))
-               dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n");
+       if (reason)
+               dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
        error->reset_count++;
  
        disable_irq(i915->drm.irq);
                goto error;
        }
  
-       i915_gem_reset(i915);
+       i915_gem_reset(i915, stalled_mask);
        intel_overlay_reset(i915);
  
        /*
@@@ -1998,7 -1993,6 +1999,6 @@@ taint
  error:
        i915_gem_set_wedged(i915);
        i915_retire_requests(i915);
-       intel_gpu_reset(i915, ALL_ENGINES);
        goto finish;
  }
  
@@@ -2011,7 -2005,7 +2011,7 @@@ static inline int intel_gt_reset_engine
  /**
   * i915_reset_engine - reset GPU engine to recover from a hang
   * @engine: engine to reset
-  * @flags: options
+  * @msg: reason for GPU reset; or NULL for no dev_notice()
   *
   * Reset a specific GPU engine. Useful if a hang is detected.
   * Returns zero on successful reset or otherwise an error code.
   *  - reset engine (which will force the engine to idle)
   *  - re-init/configure engine
   */
- int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
+ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
  {
        struct i915_gpu_error *error = &engine->i915->gpu_error;
        struct i915_request *active_request;
        int ret;
  
+       GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
        GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
  
        active_request = i915_gem_reset_prepare_engine(engine);
                goto out;
        }
  
-       if (!(flags & I915_RESET_QUIET)) {
+       if (msg)
                dev_notice(engine->i915->drm.dev,
-                          "Resetting %s after gpu hang\n", engine->name);
-       }
+                          "Resetting %s for %s\n", engine->name, msg);
        error->reset_engine_count[engine->id]++;
  
        if (!engine->i915->guc.execbuf_client)
         * active request and can drop it, adjust head to skip the offending
         * request to resume executing remaining requests in the queue.
         */
-       i915_gem_reset_engine(engine, active_request);
+       i915_gem_reset_engine(engine, active_request, true);
  
        /*
         * The engine and its registers (and workarounds in case of render)
@@@ -488,6 -488,21 +488,21 @@@ static const struct intel_limit intel_l
        .p2 = { .p2_slow = 1, .p2_fast = 20 },
  };
  
+ static void
+ skl_wa_clkgate(struct drm_i915_private *dev_priv, int pipe, bool enable)
+ {
+       if (IS_SKYLAKE(dev_priv))
+               return;
+       if (enable)
+               I915_WRITE(CLKGATE_DIS_PSL(pipe),
+                          DUPS1_GATING_DIS | DUPS2_GATING_DIS);
+       else
+               I915_WRITE(CLKGATE_DIS_PSL(pipe),
+                          I915_READ(CLKGATE_DIS_PSL(pipe)) &
+                          ~(DUPS1_GATING_DIS | DUPS2_GATING_DIS));
+ }
  static bool
  needs_modeset(const struct drm_crtc_state *state)
  {
@@@ -2657,11 -2672,13 +2672,13 @@@ static int i9xx_format_to_fourcc(int fo
        }
  }
  
static int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
+ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
  {
        switch (format) {
        case PLANE_CTL_FORMAT_RGB_565:
                return DRM_FORMAT_RGB565;
+       case PLANE_CTL_FORMAT_NV12:
+               return DRM_FORMAT_NV12;
        default:
        case PLANE_CTL_FORMAT_XRGB_8888:
                if (rgb_order) {
@@@ -2824,7 -2841,7 +2841,7 @@@ intel_find_initial_plane_obj(struct int
                        continue;
  
                if (intel_plane_ggtt_offset(state) == plane_config->base) {
 -                      fb = c->primary->fb;
 +                      fb = state->base.fb;
                        drm_framebuffer_get(fb);
                        goto valid_fb;
                }
@@@ -2858,6 -2875,9 +2875,9 @@@ valid_fb
                return;
        }
  
+       obj = intel_fb_obj(fb);
+       intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
        plane_state->src_x = 0;
        plane_state->src_y = 0;
        plane_state->src_w = fb->width << 16;
        intel_state->base.src = drm_plane_state_src(plane_state);
        intel_state->base.dst = drm_plane_state_dest(plane_state);
  
-       obj = intel_fb_obj(fb);
        if (i915_gem_object_is_tiled(obj))
                dev_priv->preserve_bios_swizzle = true;
  
@@@ -3464,6 -3483,8 +3483,8 @@@ static u32 skl_plane_ctl_format(uint32_
                return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
        case DRM_FORMAT_VYUY:
                return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
+       case DRM_FORMAT_NV12:
+               return PLANE_CTL_FORMAT_NV12;
        default:
                MISSING_CASE(pixel_format);
        }
@@@ -3611,6 -3632,11 +3632,11 @@@ u32 glk_plane_color_ctl(const struct in
        plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
  
        if (intel_format_is_yuv(fb->format->format)) {
+               if (fb->format->format == DRM_FORMAT_NV12) {
+                       plane_color_ctl |=
+                               PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
+                       goto out;
+               }
                if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
                        plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
                else
                if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
                        plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
        }
+ out:
        return plane_color_ctl;
  }
  
@@@ -3675,7 -3701,6 +3701,6 @@@ void intel_prepare_reset(struct drm_i91
        struct drm_atomic_state *state;
        int ret;
  
        /* reset doesn't touch the display */
        if (!i915_modparams.force_reset_modeset_test &&
            !gpu_reset_clobbers_display(dev_priv))
@@@ -3729,19 -3754,17 +3754,17 @@@ void intel_finish_reset(struct drm_i915
  {
        struct drm_device *dev = &dev_priv->drm;
        struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
-       struct drm_atomic_state *state = dev_priv->modeset_restore_state;
+       struct drm_atomic_state *state;
        int ret;
  
        /* reset doesn't touch the display */
-       if (!i915_modparams.force_reset_modeset_test &&
-           !gpu_reset_clobbers_display(dev_priv))
+       if (!test_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags))
                return;
  
+       state = fetch_and_zero(&dev_priv->modeset_restore_state);
        if (!state)
                goto unlock;
  
-       dev_priv->modeset_restore_state = NULL;
        /* reset doesn't touch the display */
        if (!gpu_reset_clobbers_display(dev_priv)) {
                /* for testing only restore the display */
@@@ -4703,7 -4726,9 +4726,9 @@@ static void cpt_verify_modeset(struct d
  static int
  skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
                  unsigned int scaler_user, int *scaler_id,
-                 int src_w, int src_h, int dst_w, int dst_h)
+                 int src_w, int src_h, int dst_w, int dst_h,
+                 bool plane_scaler_check,
+                 uint32_t pixel_format)
  {
        struct intel_crtc_scaler_state *scaler_state =
                &crtc_state->scaler_state;
         */
        need_scaling = src_w != dst_w || src_h != dst_h;
  
+       if (plane_scaler_check)
+               if (pixel_format == DRM_FORMAT_NV12)
+                       need_scaling = true;
        if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX)
                need_scaling = true;
  
                return 0;
        }
  
+       if (plane_scaler_check && pixel_format == DRM_FORMAT_NV12 &&
+           (src_h < SKL_MIN_YUV_420_SRC_H || (src_w % 4) != 0 ||
+            (src_h % 4) != 0)) {
+               DRM_DEBUG_KMS("NV12: src dimensions not met\n");
+               return -EINVAL;
+       }
        /* range checks */
        if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
-               dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
-               src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
-               dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) {
+           dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
+           (IS_GEN11(dev_priv) &&
+            (src_w > ICL_MAX_SRC_W || src_h > ICL_MAX_SRC_H ||
+             dst_w > ICL_MAX_DST_W || dst_h > ICL_MAX_DST_H)) ||
+           (!IS_GEN11(dev_priv) &&
+            (src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
+             dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H))) {
                DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
                        "size is out of scaler range\n",
                        intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h);
@@@ -4796,9 -4835,10 +4835,10 @@@ int skl_update_scaler_crtc(struct intel
        const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
  
        return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
-               &state->scaler_state.scaler_id,
-               state->pipe_src_w, state->pipe_src_h,
-               adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
+                                &state->scaler_state.scaler_id,
+                                state->pipe_src_w, state->pipe_src_h,
+                                adjusted_mode->crtc_hdisplay,
+                                adjusted_mode->crtc_vdisplay, false, 0);
  }
  
  /**
@@@ -4827,7 -4867,8 +4867,8 @@@ static int skl_update_scaler_plane(stru
                                drm_rect_width(&plane_state->base.src) >> 16,
                                drm_rect_height(&plane_state->base.src) >> 16,
                                drm_rect_width(&plane_state->base.dst),
-                               drm_rect_height(&plane_state->base.dst));
+                               drm_rect_height(&plane_state->base.dst),
+                               fb ? true : false, fb ? fb->format->format : 0);
  
        if (ret || plane_state->scaler_id < 0)
                return ret;
        case DRM_FORMAT_YVYU:
        case DRM_FORMAT_UYVY:
        case DRM_FORMAT_VYUY:
+       case DRM_FORMAT_NV12:
                break;
        default:
                DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
@@@ -5099,13 -5141,15 +5141,15 @@@ static bool hsw_post_update_enable_ips(
  static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
  {
        struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_atomic_state *old_state = old_crtc_state->base.state;
        struct intel_crtc_state *pipe_config =
                intel_atomic_get_new_crtc_state(to_intel_atomic_state(old_state),
                                                crtc);
        struct drm_plane *primary = crtc->base.primary;
-       struct drm_plane_state *old_pri_state =
-               drm_atomic_get_existing_plane_state(old_state, primary);
+       struct drm_plane_state *old_primary_state =
+               drm_atomic_get_old_plane_state(old_state, primary);
  
        intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
  
        if (hsw_post_update_enable_ips(old_crtc_state, pipe_config))
                hsw_enable_ips(pipe_config);
  
-       if (old_pri_state) {
-               struct intel_plane_state *primary_state =
-                       intel_atomic_get_new_plane_state(to_intel_atomic_state(old_state),
-                                                        to_intel_plane(primary));
-               struct intel_plane_state *old_primary_state =
-                       to_intel_plane_state(old_pri_state);
+       if (old_primary_state) {
+               struct drm_plane_state *new_primary_state =
+                       drm_atomic_get_new_plane_state(old_state, primary);
+               struct drm_framebuffer *fb = new_primary_state->fb;
  
                intel_fbc_post_update(crtc);
  
-               if (primary_state->base.visible &&
+               if (new_primary_state->visible &&
                    (needs_modeset(&pipe_config->base) ||
-                    !old_primary_state->base.visible))
+                    !old_primary_state->visible))
                        intel_post_enable_primary(&crtc->base, pipe_config);
+               /* Display WA 827 */
+               if ((INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv)) ||
+                   IS_CANNONLAKE(dev_priv)) {
+                       if (fb && fb->format->format == DRM_FORMAT_NV12)
+                               skl_wa_clkgate(dev_priv, crtc->pipe, false);
+               }
        }
  }
  
@@@ -5139,8 -5189,8 +5189,8 @@@ static void intel_pre_plane_update(stru
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_atomic_state *old_state = old_crtc_state->base.state;
        struct drm_plane *primary = crtc->base.primary;
-       struct drm_plane_state *old_pri_state =
-               drm_atomic_get_existing_plane_state(old_state, primary);
+       struct drm_plane_state *old_primary_state =
+               drm_atomic_get_old_plane_state(old_state, primary);
        bool modeset = needs_modeset(&pipe_config->base);
        struct intel_atomic_state *old_intel_state =
                to_intel_atomic_state(old_state);
        if (hsw_pre_update_disable_ips(old_crtc_state, pipe_config))
                hsw_disable_ips(old_crtc_state);
  
-       if (old_pri_state) {
-               struct intel_plane_state *primary_state =
+       if (old_primary_state) {
+               struct intel_plane_state *new_primary_state =
                        intel_atomic_get_new_plane_state(old_intel_state,
                                                         to_intel_plane(primary));
-               struct intel_plane_state *old_primary_state =
-                       to_intel_plane_state(old_pri_state);
+               struct drm_framebuffer *fb = new_primary_state->base.fb;
  
-               intel_fbc_pre_update(crtc, pipe_config, primary_state);
+               /* Display WA 827 */
+               if ((INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv)) ||
+                   IS_CANNONLAKE(dev_priv)) {
+                       if (fb && fb->format->format == DRM_FORMAT_NV12)
+                               skl_wa_clkgate(dev_priv, crtc->pipe, true);
+               }
+               intel_fbc_pre_update(crtc, pipe_config, new_primary_state);
                /*
                 * Gen2 reports pipe underruns whenever all planes are disabled.
                 * So disable underrun reporting before all the planes get disabled.
                 */
-               if (IS_GEN2(dev_priv) && old_primary_state->base.visible &&
-                   (modeset || !primary_state->base.visible))
+               if (IS_GEN2(dev_priv) && old_primary_state->visible &&
+                   (modeset || !new_primary_state->base.visible))
                        intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
        }
  
@@@ -8766,8 -8822,8 +8822,8 @@@ static bool ironlake_get_pipe_config(st
                        intel_get_shared_dpll_by_id(dev_priv, pll_id);
                pll = pipe_config->shared_dpll;
  
-               WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
-                                                &pipe_config->dpll_hw_state));
+               WARN_ON(!pll->info->funcs->get_hw_state(dev_priv, pll,
+                                               &pipe_config->dpll_hw_state));
  
                tmp = pipe_config->dpll_hw_state.dpll;
                pipe_config->pixel_multiplier =
@@@ -9243,8 -9299,8 +9299,8 @@@ static void haswell_get_ddi_port_state(
  
        pll = pipe_config->shared_dpll;
        if (pll) {
-               WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
-                                                &pipe_config->dpll_hw_state));
+               WARN_ON(!pll->info->funcs->get_hw_state(dev_priv, pll,
+                                               &pipe_config->dpll_hw_state));
        }
  
        /*
@@@ -9974,8 -10030,6 +10030,8 @@@ found
        ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
        if (!ret)
                ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, crtc));
 +      if (!ret)
 +              ret = drm_atomic_add_affected_planes(restore_state, crtc);
        if (ret) {
                DRM_DEBUG_KMS("Failed to create a copy of old state to restore: %i\n", ret);
                goto fail;
@@@ -10775,7 -10829,7 +10831,7 @@@ static bool check_digital_port_conflict
                struct drm_connector_state *connector_state;
                struct intel_encoder *encoder;
  
-               connector_state = drm_atomic_get_existing_connector_state(state, connector);
+               connector_state = drm_atomic_get_new_connector_state(state, connector);
                if (!connector_state)
                        connector_state = connector->state;
  
@@@ -11645,11 -11699,11 +11701,11 @@@ verify_single_dpll_state(struct drm_i91
  
        memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
  
-       DRM_DEBUG_KMS("%s\n", pll->name);
+       DRM_DEBUG_KMS("%s\n", pll->info->name);
  
-       active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state);
+       active = pll->info->funcs->get_hw_state(dev_priv, pll, &dpll_hw_state);
  
-       if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) {
+       if (!(pll->info->flags & INTEL_DPLL_ALWAYS_ON)) {
                I915_STATE_WARN(!pll->on && pll->active_mask,
                     "pll in active use but not on in sw tracking\n");
                I915_STATE_WARN(pll->on && !pll->active_mask,
@@@ -12138,20 -12192,23 +12194,23 @@@ static void intel_update_crtc(struct dr
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state);
        bool modeset = needs_modeset(new_crtc_state);
+       struct intel_plane_state *new_plane_state =
+               intel_atomic_get_new_plane_state(to_intel_atomic_state(state),
+                                                to_intel_plane(crtc->primary));
  
        if (modeset) {
                update_scanline_offset(intel_crtc);
                dev_priv->display.crtc_enable(pipe_config, state);
+               /* vblanks work again, re-enable pipe CRC. */
+               intel_crtc_enable_pipe_crc(intel_crtc);
        } else {
                intel_pre_plane_update(to_intel_crtc_state(old_crtc_state),
                                       pipe_config);
        }
  
-       if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
-               intel_fbc_enable(
-                   intel_crtc, pipe_config,
-                   to_intel_plane_state(crtc->primary->state));
-       }
+       if (new_plane_state)
+               intel_fbc_enable(intel_crtc, pipe_config, new_plane_state);
  
        drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
  }
@@@ -12322,6 -12379,13 +12381,13 @@@ static void intel_atomic_commit_tail(st
  
                if (old_crtc_state->active) {
                        intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask);
+                       /*
+                        * We need to disable pipe CRC before disabling the pipe,
+                        * or we race against vblank off.
+                        */
+                       intel_crtc_disable_pipe_crc(intel_crtc);
                        dev_priv->display.crtc_disable(to_intel_crtc_state(old_crtc_state), state);
                        intel_crtc->active = false;
                        intel_fbc_disable(intel_crtc);
@@@ -12725,8 -12789,8 +12791,8 @@@ intel_prepare_plane_fb(struct drm_plan
  
        if (old_obj) {
                struct drm_crtc_state *crtc_state =
-                       drm_atomic_get_existing_crtc_state(new_state->state,
-                                                          plane->state->crtc);
+                       drm_atomic_get_new_crtc_state(new_state->state,
+                                                     plane->state->crtc);
  
                /* Big Hammer, we also need to ensure that any pending
                 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
        if (ret)
                return ret;
  
+       intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
        if (!new_state->fence) { /* implicit fencing */
                struct dma_fence *fence;
  
@@@ -12824,11 -12890,13 +12892,13 @@@ intel_cleanup_plane_fb(struct drm_plan
  }
  
  int
- skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
+ skl_max_scale(struct intel_crtc *intel_crtc,
+             struct intel_crtc_state *crtc_state,
+             uint32_t pixel_format)
  {
        struct drm_i915_private *dev_priv;
-       int max_scale;
-       int crtc_clock, max_dotclk;
+       int max_scale, mult;
+       int crtc_clock, max_dotclk, tmpclk1, tmpclk2;
  
        if (!intel_crtc || !crtc_state->base.enable)
                return DRM_PLANE_HELPER_NO_SCALING;
         *            or
         *    cdclk/crtc_clock
         */
-       max_scale = min((1 << 16) * 3 - 1,
-                       (1 << 8) * ((max_dotclk << 8) / crtc_clock));
+       mult = pixel_format == DRM_FORMAT_NV12 ? 2 : 3;
+       tmpclk1 = (1 << 16) * mult - 1;
+       tmpclk2 = (1 << 8) * ((max_dotclk << 8) / crtc_clock);
+       max_scale = min(tmpclk1, tmpclk2);
  
        return max_scale;
  }
@@@ -12867,12 -12937,16 +12939,16 @@@ intel_check_primary_plane(struct intel_
        int max_scale = DRM_PLANE_HELPER_NO_SCALING;
        bool can_position = false;
        int ret;
+       uint32_t pixel_format = 0;
  
        if (INTEL_GEN(dev_priv) >= 9) {
                /* use scaler when colorkey is not required */
                if (!state->ckey.flags) {
                        min_scale = 1;
-                       max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
+                       if (state->base.fb)
+                               pixel_format = state->base.fb->format->format;
+                       max_scale = skl_max_scale(to_intel_crtc(crtc),
+                                                 crtc_state, pixel_format);
                }
                can_position = true;
        }
                                                           intel_cstate);
  }
  
+ void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state)
+ {
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       if (!IS_GEN2(dev_priv))
+               intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
+       if (crtc_state->has_pch_encoder) {
+               enum pipe pch_transcoder =
+                       intel_crtc_pch_transcoder(crtc);
+               intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
+       }
+ }
  static void intel_finish_crtc_commit(struct drm_crtc *crtc,
                                     struct drm_crtc_state *old_crtc_state)
  {
-       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_atomic_state *old_intel_state =
                to_intel_atomic_state(old_crtc_state->state);
  
        if (new_crtc_state->update_pipe &&
            !needs_modeset(&new_crtc_state->base) &&
-           old_crtc_state->mode.private_flags & I915_MODE_FLAG_INHERITED) {
-               if (!IS_GEN2(dev_priv))
-                       intel_set_cpu_fifo_underrun_reporting(dev_priv, intel_crtc->pipe, true);
-               if (new_crtc_state->has_pch_encoder) {
-                       enum pipe pch_transcoder =
-                               intel_crtc_pch_transcoder(intel_crtc);
-                       intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
-               }
-       }
+           old_crtc_state->mode.private_flags & I915_MODE_FLAG_INHERITED)
+               intel_crtc_arm_fifo_underrun(intel_crtc, new_crtc_state);
  }
  
  /**
@@@ -13167,8 -13247,9 +13249,9 @@@ intel_legacy_cursor_update(struct drm_p
        if (ret)
                goto out_unlock;
  
-       old_fb = old_plane_state->fb;
+       intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_FLIP);
  
+       old_fb = old_plane_state->fb;
        i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
                          intel_plane->frontbuffer_bit);
  
@@@ -13555,10 -13636,17 +13638,17 @@@ static int intel_crtc_init(struct drm_i
        /* initialize shared scalers */
        intel_crtc_init_scalers(intel_crtc, crtc_state);
  
-       BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
-              dev_priv->plane_to_crtc_mapping[primary->i9xx_plane] != NULL);
-       dev_priv->plane_to_crtc_mapping[primary->i9xx_plane] = intel_crtc;
-       dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = intel_crtc;
+       BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) ||
+              dev_priv->pipe_to_crtc_mapping[pipe] != NULL);
+       dev_priv->pipe_to_crtc_mapping[pipe] = intel_crtc;
+       if (INTEL_GEN(dev_priv) < 9) {
+               enum i9xx_plane_id i9xx_plane = primary->i9xx_plane;
+               BUG_ON(i9xx_plane >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
+                      dev_priv->plane_to_crtc_mapping[i9xx_plane] != NULL);
+               dev_priv->plane_to_crtc_mapping[i9xx_plane] = intel_crtc;
+       }
  
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
  
@@@ -15103,8 -15191,8 +15193,8 @@@ static void intel_modeset_readout_hw_st
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
  
-               pll->on = pll->funcs.get_hw_state(dev_priv, pll,
-                                                 &pll->state.hw_state);
+               pll->on = pll->info->funcs->get_hw_state(dev_priv, pll,
+                                                       &pll->state.hw_state);
                pll->state.crtc_mask = 0;
                for_each_intel_crtc(dev, crtc) {
                        struct intel_crtc_state *crtc_state =
                pll->active_mask = pll->state.crtc_mask;
  
                DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
-                             pll->name, pll->state.crtc_mask, pll->on);
+                             pll->info->name, pll->state.crtc_mask, pll->on);
        }
  
        for_each_intel_encoder(dev, encoder) {
@@@ -15291,9 -15379,10 +15381,10 @@@ intel_modeset_setup_hw_state(struct drm
                if (!pll->on || pll->active_mask)
                        continue;
  
-               DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
+               DRM_DEBUG_KMS("%s enabled but not in use, disabling\n",
+                             pll->info->name);
  
-               pll->funcs.disable(dev_priv, pll);
+               pll->info->funcs->disable(dev_priv, pll);
                pll->on = false;
        }
  
   * check the condition before the timeout.
   */
  #define __wait_for(OP, COND, US, Wmin, Wmax) ({ \
 -      unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1;   \
 +      const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \
        long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \
        int ret__;                                                      \
        might_sleep();                                                  \
        for (;;) {                                                      \
 -              bool expired__ = time_after(jiffies, timeout__);        \
 +              const bool expired__ = ktime_after(ktime_get_raw(), end__); \
                OP;                                                     \
                if (COND) {                                             \
                        ret__ = 0;                                      \
@@@ -482,7 -482,7 +482,7 @@@ struct intel_atomic_state 
        bool skip_intermediate_wm;
  
        /* Gen9+ only */
-       struct skl_wm_values wm_results;
+       struct skl_ddb_values wm_results;
  
        struct i915_sw_fence commit_ready;
  
@@@ -548,6 -548,12 +548,12 @@@ struct intel_initial_plane_config 
  #define SKL_MAX_DST_W 4096
  #define SKL_MIN_DST_H 8
  #define SKL_MAX_DST_H 4096
+ #define ICL_MAX_SRC_W 5120
+ #define ICL_MAX_SRC_H 4096
+ #define ICL_MAX_DST_W 5120
+ #define ICL_MAX_DST_H 4096
+ #define SKL_MIN_YUV_420_SRC_W 16
+ #define SKL_MIN_YUV_420_SRC_H 16
  
  struct intel_scaler {
        int in_use;
@@@ -598,7 -604,9 +604,9 @@@ struct intel_pipe_wm 
  
  struct skl_plane_wm {
        struct skl_wm_level wm[8];
+       struct skl_wm_level uv_wm[8];
        struct skl_wm_level trans_wm;
+       bool is_planar;
  };
  
  struct skl_pipe_wm {
@@@ -1325,6 -1333,7 +1333,7 @@@ void gen5_enable_gt_irq(struct drm_i915
  void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
  void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask);
  void gen6_unmask_pm_irq(struct drm_i915_private *dev_priv, u32 mask);
+ void gen11_reset_rps_interrupts(struct drm_i915_private *dev_priv);
  void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv);
  void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv);
  void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv);
@@@ -1588,9 -1597,12 +1597,12 @@@ void hsw_disable_ips(const struct intel
  enum intel_display_power_domain intel_port_to_power_domain(enum port port);
  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
                                 struct intel_crtc_state *pipe_config);
+ void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state);
  
  int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
- int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
+ int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+                 uint32_t pixel_format);
  
  static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
  {
@@@ -1607,6 -1619,7 +1619,7 @@@ u32 skl_plane_stride(const struct drm_f
  int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
                            struct intel_plane_state *plane_state);
  int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
+ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
  
  /* intel_csr.c */
  void intel_csr_ucode_init(struct drm_i915_private *);
@@@ -1773,6 -1786,7 +1786,7 @@@ void intel_fbc_flush(struct drm_i915_pr
                     unsigned int frontbuffer_bits, enum fb_op_origin origin);
  void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
  void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv);
+ int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv);
  
  /* intel_hdmi.c */
  void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg,
@@@ -1783,7 -1797,7 +1797,7 @@@ struct intel_hdmi *enc_to_intel_hdmi(st
  bool intel_hdmi_compute_config(struct intel_encoder *encoder,
                               struct intel_crtc_state *pipe_config,
                               struct drm_connector_state *conn_state);
void intel_hdmi_handle_sink_scrambling(struct intel_encoder *intel_encoder,
bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
                                       struct drm_connector *connector,
                                       bool high_tmds_clock_ratio,
                                       bool scrambling);
@@@ -1877,7 -1891,8 +1891,8 @@@ void intel_psr_enable(struct intel_dp *
  void intel_psr_disable(struct intel_dp *intel_dp,
                      const struct intel_crtc_state *old_crtc_state);
  void intel_psr_invalidate(struct drm_i915_private *dev_priv,
-                         unsigned frontbuffer_bits);
+                         unsigned frontbuffer_bits,
+                         enum fb_op_origin origin);
  void intel_psr_flush(struct drm_i915_private *dev_priv,
                     unsigned frontbuffer_bits,
                     enum fb_op_origin origin);
@@@ -2046,6 -2061,7 +2061,7 @@@ void skl_disable_plane(struct intel_pla
  bool skl_plane_get_hw_state(struct intel_plane *plane);
  bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
                       enum pipe pipe, enum plane_id plane_id);
+ bool intel_format_is_yuv(uint32_t format);
  
  /* intel_tv.c */
  void intel_tv_init(struct drm_i915_private *dev_priv);
@@@ -2082,31 -2098,6 +2098,6 @@@ intel_atomic_get_crtc_state(struct drm_
        return to_intel_crtc_state(crtc_state);
  }
  
- static inline struct intel_crtc_state *
- intel_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
-                                    struct intel_crtc *crtc)
- {
-       struct drm_crtc_state *crtc_state;
-       crtc_state = drm_atomic_get_existing_crtc_state(state, &crtc->base);
-       if (crtc_state)
-               return to_intel_crtc_state(crtc_state);
-       else
-               return NULL;
- }
- static inline struct intel_plane_state *
- intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
-                                     struct intel_plane *plane)
- {
-       struct drm_plane_state *plane_state;
-       plane_state = drm_atomic_get_existing_plane_state(state, &plane->base);
-       return to_intel_plane_state(plane_state);
- }
  int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
                               struct intel_crtc *intel_crtc,
                               struct intel_crtc_state *crtc_state);
@@@ -2138,8 -2129,17 +2129,17 @@@ int intel_pipe_crc_create(struct drm_mi
  #ifdef CONFIG_DEBUG_FS
  int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
                              size_t *values_cnt);
+ void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc);
+ void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc);
  #else
  #define intel_crtc_set_crc_source NULL
+ static inline void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
+ {
+ }
+ static inline void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
+ {
+ }
  #endif
  extern const struct file_operations i915_display_crc_ctl_fops;
  #endif /* __INTEL_DRV_H__ */
@@@ -221,6 -221,9 +221,9 @@@ static int intelfb_create(struct drm_fb
                goto out_unlock;
        }
  
+       fb = &ifbdev->fb->base;
+       intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB);
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
                DRM_ERROR("Failed to allocate fb_info\n");
  
        info->par = helper;
  
-       fb = &ifbdev->fb->base;
        ifbdev->helper.fb = fb;
  
        strcpy(info->fix.id, "inteldrmfb");
@@@ -640,7 -641,7 +641,7 @@@ static bool intel_fbdev_init_bios(struc
                if (!crtc->state->active)
                        continue;
  
 -              WARN(!crtc->primary->fb,
 +              WARN(!crtc->primary->state->fb,
                     "re-used BIOS config but lost an fb on crtc %d\n",
                     crtc->base.id);
        }
@@@ -806,7 -807,7 +807,7 @@@ void intel_fbdev_output_poll_changed(st
                return;
  
        intel_fbdev_sync(ifbdev);
 -      if (ifbdev->vma)
 +      if (ifbdev->vma || ifbdev->helper.deferred_setup)
                drm_fb_helper_hotplug_event(&ifbdev->helper);
  }