Merge drm/drm-next into drm-misc-next
authorMaxime Ripard <maxime.ripard@bootlin.com>
Fri, 11 Jan 2019 15:32:10 +0000 (16:32 +0100)
committerMaxime Ripard <maxime.ripard@bootlin.com>
Fri, 11 Jan 2019 15:32:10 +0000 (16:32 +0100)
drm-next has been forwarded to 5.0-rc1, and we need it to apply the damage
helper for dirtyfb series from Noralf Trønnes.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
20 files changed:
1  2 
Documentation/gpu/drm-kms-helpers.rst
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/omapdrm/omap_encoder.c
drivers/gpu/drm/tegra/sor.c
include/drm/drm_connector.h
include/drm/drm_crtc.h

index 27001ae5d37082844a2df1c47f3a86456fb780dc,b422eb8edf1627baba10a231560eca754e31e846..7a3fc569bc688e688bffa9a5b5c77fe9a393dd82
@@@ -208,40 -208,18 +208,40 @@@ Display Port Dual Mode Adaptor Helper F
  .. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c
     :export:
  
 -Display Port MST Helper Functions Reference
 -===========================================
 +Display Port MST Helpers
 +========================
 +
 +Overview
 +--------
  
  .. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
     :doc: dp mst helper
  
 +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
 +   :doc: Branch device and port refcounting
 +
 +Functions Reference
 +-------------------
 +
  .. kernel-doc:: include/drm/drm_dp_mst_helper.h
     :internal:
  
  .. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
     :export:
  
 +Topology Lifetime Internals
 +---------------------------
 +
 +These functions aren't exported to drivers, but are documented here to help make
 +the MST topology helpers easier to understand
 +
 +.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
 +   :functions: drm_dp_mst_topology_try_get_mstb drm_dp_mst_topology_get_mstb
 +               drm_dp_mst_topology_put_mstb
 +               drm_dp_mst_topology_try_get_port drm_dp_mst_topology_get_port
 +               drm_dp_mst_topology_put_port
 +               drm_dp_mst_get_mstb_malloc drm_dp_mst_put_mstb_malloc
 +
  MIPI DSI Helper Functions Reference
  ===================================
  
  .. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c
     :export:
  
+ Display Stream Compression Helper Functions Reference
+ =====================================================
+ .. kernel-doc:: drivers/gpu/drm/drm_dsc.c
+    :doc: dsc helpers
+ .. kernel-doc:: include/drm/drm_dsc.h
+    :internal:
+ .. kernel-doc:: drivers/gpu/drm/drm_dsc.c
+    :export:
  Output Probing Helper Functions Reference
  =========================================
  
index 24665795b1ad4d9fc40eabbd51f182e72cf458b2,5e7ca1f3a8d1a2606e15aa73293c56f173ad9b9b..24632727e12707dd5eb51eb1653331772c10a85c
@@@ -191,7 -191,6 +191,7 @@@ dm_dp_mst_connector_destroy(struct drm_
        drm_encoder_cleanup(&amdgpu_encoder->base);
        kfree(amdgpu_encoder);
        drm_connector_cleanup(connector);
 +      drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
        kfree(amdgpu_dm_connector);
  }
  
@@@ -343,10 -342,9 +343,9 @@@ dm_dp_add_mst_connector(struct drm_dp_m
                master->connector_id);
  
        aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master);
+       drm_connector_attach_encoder(&aconnector->base,
+                                    &aconnector->mst_encoder->base);
  
-       /*
-        * TODO: understand why this one is needed
-        */
        drm_object_attach_property(
                &connector->base,
                dev->mode_config.path_property,
        amdgpu_dm_connector_funcs_reset(connector);
  
        DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
 -                      aconnector, connector->base.id, aconnector->mst_port);
 +               aconnector, connector->base.id, aconnector->mst_port);
 +
 +      drm_dp_mst_get_port_malloc(port);
  
        DRM_DEBUG_KMS(":%d\n", connector->base.id);
  
@@@ -383,12 -379,12 +382,12 @@@ static void dm_dp_destroy_mst_connector
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
  
        DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
 -                              aconnector, connector->base.id, aconnector->mst_port);
 +               aconnector, connector->base.id, aconnector->mst_port);
  
 -      aconnector->port = NULL;
        if (aconnector->dc_sink) {
                amdgpu_dm_update_freesync_caps(connector, NULL);
 -              dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink);
 +              dc_link_remove_remote_sink(aconnector->dc_link,
 +                                         aconnector->dc_sink);
                dc_sink_release(aconnector->dc_sink);
                aconnector->dc_sink = NULL;
        }
index e224b9b7d17ac73f68bf67ee4db0f2c9f942221a,1593dd6cdfb729c3bdfe19215947314df1f0a74d..f660819d406efb586fe2547a6585a5a9d4c0b02a
@@@ -93,6 -93,15 +93,6 @@@ struct drm_crtc *drm_crtc_from_index(st
  }
  EXPORT_SYMBOL(drm_crtc_from_index);
  
 -/**
 - * drm_crtc_force_disable - Forcibly turn off a CRTC
 - * @crtc: CRTC to turn off
 - *
 - * Note: This should only be used by non-atomic legacy drivers.
 - *
 - * Returns:
 - * Zero on success, error code on failure.
 - */
  int drm_crtc_force_disable(struct drm_crtc *crtc)
  {
        struct drm_mode_set set = {
  
        return drm_mode_set_config_internal(&set);
  }
 -EXPORT_SYMBOL(drm_crtc_force_disable);
  
  /**
   * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
@@@ -330,6 -340,8 +330,8 @@@ int drm_crtc_init_with_planes(struct dr
                drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
                drm_object_attach_property(&crtc->base,
                                           config->prop_out_fence_ptr, 0);
+               drm_object_attach_property(&crtc->base,
+                                          config->prop_vrr_enabled, 0);
        }
  
        return 0;
index 883a0c44714c58821284de2da67d5ed7c039bde5,d3af098b0922320f2c8be1db7d779ae91538618d..ca706fb1d975e9faac6e05e7b8222bd2781444c7
@@@ -71,7 -71,7 +71,7 @@@ MODULE_PARM_DESC(drm_fbdev_overalloc
  #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
  static bool drm_leak_fbdev_smem = false;
  module_param_unsafe(drm_leak_fbdev_smem, bool, 0600);
- MODULE_PARM_DESC(fbdev_emulation,
+ MODULE_PARM_DESC(drm_leak_fbdev_smem,
                 "Allow unsafe leaking fbdev physical smem address [default=false]");
  #endif
  
@@@ -1797,7 -1797,6 +1797,7 @@@ static int drm_fb_helper_single_fb_prob
        int i;
        struct drm_fb_helper_surface_size sizes;
        int gamma_size = 0;
 +      int best_depth = 0;
  
        memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size));
        sizes.surface_depth = 24;
        sizes.fb_width = (u32)-1;
        sizes.fb_height = (u32)-1;
  
 -      /* if driver picks 8 or 16 by default use that for both depth/bpp */
 +      /*
 +       * If driver picks 8 or 16 by default use that for both depth/bpp
 +       * to begin with
 +       */
        if (preferred_bpp != sizes.surface_bpp)
                sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
  
                }
        }
  
 +      /*
 +       * If we run into a situation where, for example, the primary plane
 +       * supports RGBA5551 (16 bpp, depth 15) but not RGB565 (16 bpp, depth
 +       * 16) we need to scale down the depth of the sizes we request.
 +       */
 +      for (i = 0; i < fb_helper->crtc_count; i++) {
 +              struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
 +              struct drm_crtc *crtc = mode_set->crtc;
 +              struct drm_plane *plane = crtc->primary;
 +              int j;
 +
 +              DRM_DEBUG("test CRTC %d primary plane\n", i);
 +
 +              for (j = 0; j < plane->format_count; j++) {
 +                      const struct drm_format_info *fmt;
 +
 +                      fmt = drm_format_info(plane->format_types[j]);
 +
 +                      /*
 +                       * Do not consider YUV or other complicated formats
 +                       * for framebuffers. This means only legacy formats
 +                       * are supported (fmt->depth is a legacy field) but
 +                       * the framebuffer emulation can only deal with such
 +                       * formats, specifically RGB/BGA formats.
 +                       */
 +                      if (fmt->depth == 0)
 +                              continue;
 +
 +                      /* We found a perfect fit, great */
 +                      if (fmt->depth == sizes.surface_depth) {
 +                              best_depth = fmt->depth;
 +                              break;
 +                      }
 +
 +                      /* Skip depths above what we're looking for */
 +                      if (fmt->depth > sizes.surface_depth)
 +                              continue;
 +
 +                      /* Best depth found so far */
 +                      if (fmt->depth > best_depth)
 +                              best_depth = fmt->depth;
 +              }
 +      }
 +      if (sizes.surface_depth != best_depth) {
 +              DRM_INFO("requested bpp %d, scaled depth down to %d",
 +                       sizes.surface_bpp, best_depth);
 +              sizes.surface_depth = best_depth;
 +      }
 +
        crtc_count = 0;
        for (i = 0; i < fb_helper->crtc_count; i++) {
                struct drm_display_mode *desired_mode;
@@@ -2919,7 -2866,7 +2919,7 @@@ int drm_fb_helper_fbdev_setup(struct dr
        return 0;
  
  err_drm_fb_helper_fini:
 -      drm_fb_helper_fini(fb_helper);
 +      drm_fb_helper_fbdev_teardown(dev);
  
        return ret;
  }
@@@ -3014,16 -2961,18 +3014,16 @@@ static int drm_fbdev_fb_release(struct 
        return 0;
  }
  
 -/*
 - * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
 - * unregister_framebuffer() or fb_release().
 - */
 -static void drm_fbdev_fb_destroy(struct fb_info *info)
 +static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
  {
 -      struct drm_fb_helper *fb_helper = info->par;
        struct fb_info *fbi = fb_helper->fbdev;
        struct fb_ops *fbops = NULL;
        void *shadow = NULL;
  
 -      if (fbi->fbdefio) {
 +      if (!fb_helper->dev)
 +              return;
 +
 +      if (fbi && fbi->fbdefio) {
                fb_deferred_io_cleanup(fbi);
                shadow = fbi->screen_buffer;
                fbops = fbi->fbops;
        }
  
        drm_client_framebuffer_delete(fb_helper->buffer);
 +}
 +
 +static void drm_fbdev_release(struct drm_fb_helper *fb_helper)
 +{
 +      drm_fbdev_cleanup(fb_helper);
 +
        /*
         * FIXME:
         * Remove conditional when all CMA drivers have been moved over to using
        }
  }
  
 +/*
 + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
 + * unregister_framebuffer() or fb_release().
 + */
 +static void drm_fbdev_fb_destroy(struct fb_info *info)
 +{
 +      drm_fbdev_release(info->par);
 +}
 +
  static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
  {
        struct drm_fb_helper *fb_helper = info->par;
@@@ -3113,6 -3047,7 +3113,6 @@@ int drm_fb_helper_generic_probe(struct 
        struct drm_framebuffer *fb;
        struct fb_info *fbi;
        u32 format;
 -      int ret;
  
        DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
                      sizes->surface_width, sizes->surface_height,
        fb = buffer->fb;
  
        fbi = drm_fb_helper_alloc_fbi(fb_helper);
 -      if (IS_ERR(fbi)) {
 -              ret = PTR_ERR(fbi);
 -              goto err_free_buffer;
 -      }
 +      if (IS_ERR(fbi))
 +              return PTR_ERR(fbi);
  
        fbi->par = fb_helper;
        fbi->fbops = &drm_fbdev_fb_ops;
                if (!fbops || !shadow) {
                        kfree(fbops);
                        vfree(shadow);
 -                      ret = -ENOMEM;
 -                      goto err_fb_info_destroy;
 +                      return -ENOMEM;
                }
  
                *fbops = *fbi->fbops;
        }
  
        return 0;
 -
 -err_fb_info_destroy:
 -      drm_fb_helper_fini(fb_helper);
 -err_free_buffer:
 -      drm_client_framebuffer_delete(buffer);
 -
 -      return ret;
  }
  EXPORT_SYMBOL(drm_fb_helper_generic_probe);
  
@@@ -3184,11 -3129,18 +3184,11 @@@ static void drm_fbdev_client_unregister
  {
        struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
  
 -      if (fb_helper->fbdev) {
 -              drm_fb_helper_unregister_fbi(fb_helper);
 +      if (fb_helper->fbdev)
                /* drm_fbdev_fb_destroy() takes care of cleanup */
 -              return;
 -      }
 -
 -      /* Did drm_fb_helper_fbdev_setup() run? */
 -      if (fb_helper->dev)
 -              drm_fb_helper_fini(fb_helper);
 -
 -      drm_client_release(client);
 -      kfree(fb_helper);
 +              drm_fb_helper_unregister_fbi(fb_helper);
 +      else
 +              drm_fbdev_release(fb_helper);
  }
  
  static int drm_fbdev_client_restore(struct drm_client_dev *client)
@@@ -3206,7 -3158,7 +3206,7 @@@ static int drm_fbdev_client_hotplug(str
        struct drm_device *dev = client->dev;
        int ret;
  
 -      /* If drm_fb_helper_fbdev_setup() failed, we only try once */
 +      /* Setup is not retried if it has failed */
        if (!fb_helper->dev && fb_helper->funcs)
                return 0;
  
                return 0;
        }
  
 -      ret = drm_fb_helper_fbdev_setup(dev, fb_helper, &drm_fb_helper_generic_funcs,
 -                                      fb_helper->preferred_bpp, 0);
 -      if (ret) {
 -              fb_helper->dev = NULL;
 -              fb_helper->fbdev = NULL;
 -              return ret;
 -      }
 +      drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs);
 +
 +      ret = drm_fb_helper_init(dev, fb_helper, dev->mode_config.num_connector);
 +      if (ret)
 +              goto err;
 +
 +      ret = drm_fb_helper_single_add_all_connectors(fb_helper);
 +      if (ret)
 +              goto err_cleanup;
 +
 +      if (!drm_drv_uses_atomic_modeset(dev))
 +              drm_helper_disable_unused_functions(dev);
 +
 +      ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp);
 +      if (ret)
 +              goto err_cleanup;
  
        return 0;
 +
 +err_cleanup:
 +      drm_fbdev_cleanup(fb_helper);
 +err:
 +      fb_helper->dev = NULL;
 +      fb_helper->fbdev = NULL;
 +
 +      DRM_DEV_ERROR(dev->dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);
 +
 +      return ret;
  }
  
  static const struct drm_client_funcs drm_fbdev_client_funcs = {
@@@ -3304,10 -3237,6 +3304,10 @@@ int drm_fbdev_generic_setup(struct drm_
  
        drm_client_add(&fb_helper->client);
  
 +      if (!preferred_bpp)
 +              preferred_bpp = dev->mode_config.preferred_depth;
 +      if (!preferred_bpp)
 +              preferred_bpp = 32;
        fb_helper->preferred_bpp = preferred_bpp;
  
        ret = drm_fbdev_client_hotplug(&fb_helper->client);
index a63d084c8e9688cfbf8759d66b63b4ffe46c0598,38dcee1ca062483272948bce3a7d9af2b4c83a7d..9bad6a32adaef35ba0ccd56ee114687e8ae812e4
@@@ -943,30 -943,30 +943,30 @@@ static int i915_gem_fence_regs_info(str
  static ssize_t gpu_state_read(struct file *file, char __user *ubuf,
                              size_t count, loff_t *pos)
  {
-       struct i915_gpu_state *error = file->private_data;
-       struct drm_i915_error_state_buf str;
+       struct i915_gpu_state *error;
        ssize_t ret;
-       loff_t tmp;
+       void *buf;
  
+       error = file->private_data;
        if (!error)
                return 0;
  
-       ret = i915_error_state_buf_init(&str, error->i915, count, *pos);
-       if (ret)
-               return ret;
+       /* Bounce buffer required because of kernfs __user API convenience. */
+       buf = kmalloc(count, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
  
-       ret = i915_error_state_to_str(&str, error);
-       if (ret)
+       ret = i915_gpu_state_copy_to_buffer(error, buf, *pos, count);
+       if (ret <= 0)
                goto out;
  
-       tmp = 0;
-       ret = simple_read_from_buffer(ubuf, count, &tmp, str.buf, str.bytes);
-       if (ret < 0)
-               goto out;
+       if (!copy_to_user(ubuf, buf, ret))
+               *pos += ret;
+       else
+               ret = -EFAULT;
  
-       *pos = str.start + ret;
  out:
-       i915_error_state_buf_release(&str);
+       kfree(buf);
        return ret;
  }
  
@@@ -2948,7 -2948,14 +2948,7 @@@ static void intel_seq_print_mode(struc
        for (i = 0; i < tabs; i++)
                seq_putc(m, '\t');
  
 -      seq_printf(m, "id %d:\"%s\" freq %d clock %d hdisp %d hss %d hse %d htot %d vdisp %d vss %d vse %d vtot %d type 0x%x flags 0x%x\n",
 -                 mode->base.id, mode->name,
 -                 mode->vrefresh, mode->clock,
 -                 mode->hdisplay, mode->hsync_start,
 -                 mode->hsync_end, mode->htotal,
 -                 mode->vdisplay, mode->vsync_start,
 -                 mode->vsync_end, mode->vtotal,
 -                 mode->type, mode->flags);
 +      seq_printf(m, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
  }
  
  static void intel_encoder_info(struct seq_file *m,
@@@ -3368,13 -3375,15 +3368,15 @@@ static int i915_shared_dplls_info(struc
  
  static int i915_wa_registers(struct seq_file *m, void *unused)
  {
-       struct i915_workarounds *wa = &node_to_i915(m->private)->workarounds;
-       int i;
+       struct drm_i915_private *i915 = node_to_i915(m->private);
+       const struct i915_wa_list *wal = &i915->engine[RCS]->ctx_wa_list;
+       struct i915_wa *wa;
+       unsigned int i;
  
-       seq_printf(m, "Workarounds applied: %d\n", wa->count);
-       for (i = 0; i < wa->count; ++i)
+       seq_printf(m, "Workarounds applied: %u\n", wal->count);
+       for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
                seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n",
-                          wa->reg[i].addr, wa->reg[i].value, wa->reg[i].mask);
+                          i915_mmio_reg_offset(wa->reg), wa->val, wa->mask);
  
        return 0;
  }
@@@ -3434,31 -3443,32 +3436,32 @@@ static int i915_ddb_info(struct seq_fil
  {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
        struct drm_device *dev = &dev_priv->drm;
-       struct skl_ddb_allocation *ddb;
        struct skl_ddb_entry *entry;
-       enum pipe pipe;
-       int plane;
+       struct intel_crtc *crtc;
  
        if (INTEL_GEN(dev_priv) < 9)
                return -ENODEV;
  
        drm_modeset_lock_all(dev);
  
-       ddb = &dev_priv->wm.skl_hw.ddb;
        seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
  
-       for_each_pipe(dev_priv, pipe) {
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
+               struct intel_crtc_state *crtc_state =
+                       to_intel_crtc_state(crtc->base.state);
+               enum pipe pipe = crtc->pipe;
+               enum plane_id plane_id;
                seq_printf(m, "Pipe %c\n", pipe_name(pipe));
  
-               for_each_universal_plane(dev_priv, pipe, plane) {
-                       entry = &ddb->plane[pipe][plane];
-                       seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane + 1,
+               for_each_plane_id_on_crtc(crtc, plane_id) {
+                       entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
+                       seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
                                   entry->start, entry->end,
                                   skl_ddb_entry_size(entry));
                }
  
-               entry = &ddb->plane[pipe][PLANE_CURSOR];
+               entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
                seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
                           entry->end, skl_ddb_entry_size(entry));
        }
@@@ -4585,6 -4595,13 +4588,13 @@@ static int i915_hpd_storm_ctl_show(stru
        struct drm_i915_private *dev_priv = m->private;
        struct i915_hotplug *hotplug = &dev_priv->hotplug;
  
+       /* Synchronize with everything first in case there's been an HPD
+        * storm, but we haven't finished handling it in the kernel yet
+        */
+       synchronize_irq(dev_priv->drm.irq);
+       flush_work(&dev_priv->hotplug.dig_port_work);
+       flush_work(&dev_priv->hotplug.hotplug_work);
        seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
        seq_printf(m, "Detected: %s\n",
                   yesno(delayed_work_pending(&hotplug->reenable_work)));
index 5a679af03a04a4ea91ca61e3f67024ba9a7d0a6f,3da9c0f9e9485c7c4b9ccf8fefe5c71f72f1ea02..20beb1977a27b52c0766327a823892cf01328d07
@@@ -46,7 -46,7 +46,7 @@@
  #include <drm/drm_plane_helper.h>
  #include <drm/drm_rect.h>
  #include <drm/drm_atomic_uapi.h>
- #include <linux/dma_remapping.h>
+ #include <linux/intel-iommu.h>
  #include <linux/reservation.h>
  
  /* Primary plane formats for gen <= 3 */
@@@ -2341,10 -2341,26 +2341,26 @@@ static int intel_fb_offset_to_xy(int *x
                                 int color_plane)
  {
        struct drm_i915_private *dev_priv = to_i915(fb->dev);
+       unsigned int height;
  
        if (fb->modifier != DRM_FORMAT_MOD_LINEAR &&
-           fb->offsets[color_plane] % intel_tile_size(dev_priv))
+           fb->offsets[color_plane] % intel_tile_size(dev_priv)) {
+               DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n",
+                             fb->offsets[color_plane], color_plane);
                return -EINVAL;
+       }
+       height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
+       height = ALIGN(height, intel_tile_height(fb, color_plane));
+       /* Catch potential overflows early */
+       if (add_overflows_t(u32, mul_u32_u32(height, fb->pitches[color_plane]),
+                           fb->offsets[color_plane])) {
+               DRM_DEBUG_KMS("Bad offset 0x%08x or pitch %d for color plane %d\n",
+                             fb->offsets[color_plane], fb->pitches[color_plane],
+                             color_plane);
+               return -ERANGE;
+       }
  
        *x = 0;
        *y = 0;
@@@ -2767,7 -2783,7 +2783,7 @@@ static void intel_plane_disable_noatomi
                intel_pre_disable_primary_noatomic(&crtc->base);
  
        trace_intel_disable_plane(&plane->base, crtc);
-       plane->disable_plane(plane, crtc);
+       plane->disable_plane(plane, crtc_state);
  }
  
  static void
@@@ -3315,7 -3331,6 +3331,6 @@@ static void i9xx_update_plane(struct in
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
        u32 linear_offset;
        u32 dspcntr = plane_state->ctl;
-       i915_reg_t reg = DSPCNTR(i9xx_plane);
        int x = plane_state->color_plane[0].x;
        int y = plane_state->color_plane[0].y;
        unsigned long irqflags;
  
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  
+       I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
        if (INTEL_GEN(dev_priv) < 4) {
                /* pipesrc and dspsize control the size that is scaled from,
                 * which should always be the user's requested size.
                 */
+               I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
                I915_WRITE_FW(DSPSIZE(i9xx_plane),
                              ((crtc_state->pipe_src_h - 1) << 16) |
                              (crtc_state->pipe_src_w - 1));
-               I915_WRITE_FW(DSPPOS(i9xx_plane), 0);
        } else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
+               I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
                I915_WRITE_FW(PRIMSIZE(i9xx_plane),
                              ((crtc_state->pipe_src_h - 1) << 16) |
                              (crtc_state->pipe_src_w - 1));
-               I915_WRITE_FW(PRIMPOS(i9xx_plane), 0);
                I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0);
        }
  
-       I915_WRITE_FW(reg, dspcntr);
-       I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
-               I915_WRITE_FW(DSPSURF(i9xx_plane),
-                             intel_plane_ggtt_offset(plane_state) +
-                             dspaddr_offset);
                I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x);
        } else if (INTEL_GEN(dev_priv) >= 4) {
+               I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
+               I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
+       }
+       /*
+        * The control register self-arms if the plane was previously
+        * disabled. Try to make the plane enable atomic by writing
+        * the control register just before the surface register.
+        */
+       I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr);
+       if (INTEL_GEN(dev_priv) >= 4)
                I915_WRITE_FW(DSPSURF(i9xx_plane),
                              intel_plane_ggtt_offset(plane_state) +
                              dspaddr_offset);
-               I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x);
-               I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset);
-       } else {
+       else
                I915_WRITE_FW(DSPADDR(i9xx_plane),
                              intel_plane_ggtt_offset(plane_state) +
                              dspaddr_offset);
-       }
  
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  }
  
  static void i9xx_disable_plane(struct intel_plane *plane,
-                              struct intel_crtc *crtc)
+                              const struct intel_crtc_state *crtc_state)
  {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
@@@ -3456,6 -3475,21 +3475,21 @@@ static void skl_detach_scalers(const st
        }
  }
  
+ static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
+                                         int color_plane, unsigned int rotation)
+ {
+       /*
+        * The stride is either expressed as a multiple of 64 bytes chunks for
+        * linear buffers or in number of tiles for tiled buffers.
+        */
+       if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
+               return 64;
+       else if (drm_rotation_90_or_270(rotation))
+               return intel_tile_height(fb, color_plane);
+       else
+               return intel_tile_width_bytes(fb, color_plane);
+ }
  u32 skl_plane_stride(const struct intel_plane_state *plane_state,
                     int color_plane)
  {
        if (color_plane >= fb->format->num_planes)
                return 0;
  
-       /*
-        * The stride is either expressed as a multiple of 64 bytes chunks for
-        * linear buffers or in number of tiles for tiled buffers.
-        */
-       if (drm_rotation_90_or_270(rotation))
-               stride /= intel_tile_height(fb, color_plane);
-       else
-               stride /= intel_fb_stride_alignment(fb, color_plane);
-       return stride;
+       return stride / skl_plane_stride_mult(fb, color_plane, rotation);
  }
  
  static u32 skl_plane_ctl_format(uint32_t pixel_format)
@@@ -5403,23 -5428,32 +5428,32 @@@ static void intel_pre_plane_update(stru
                intel_update_watermarks(crtc);
  }
  
- static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask)
+ static void intel_crtc_disable_planes(struct intel_atomic_state *state,
+                                     struct intel_crtc *crtc)
  {
-       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       const struct intel_crtc_state *new_crtc_state =
+               intel_atomic_get_new_crtc_state(state, crtc);
+       unsigned int update_mask = new_crtc_state->update_planes;
+       const struct intel_plane_state *old_plane_state;
        struct intel_plane *plane;
        unsigned fb_bits = 0;
+       int i;
  
        intel_crtc_dpms_overlay_disable(crtc);
  
-       for_each_intel_plane_on_crtc(dev, crtc, plane) {
-               if (plane_mask & BIT(plane->id)) {
-                       plane->disable_plane(plane, crtc);
+       for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
+               if (crtc->pipe != plane->pipe ||
+                   !(update_mask & BIT(plane->id)))
+                       continue;
  
+               plane->disable_plane(plane, new_crtc_state);
+               if (old_plane_state->base.visible)
                        fb_bits |= plane->frontbuffer_bit;
-               }
        }
  
-       intel_frontbuffer_flip(to_i915(dev), fb_bits);
+       intel_frontbuffer_flip(dev_priv, fb_bits);
  }
  
  static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc,
@@@ -5692,9 -5726,6 +5726,6 @@@ static void haswell_crtc_enable(struct 
        if (pipe_config->shared_dpll)
                intel_enable_shared_dpll(pipe_config);
  
-       if (INTEL_GEN(dev_priv) >= 11)
-               icl_map_plls_to_ports(crtc, pipe_config, old_state);
        intel_encoders_pre_enable(crtc, pipe_config, old_state);
  
        if (intel_crtc_has_dp_encoder(pipe_config))
@@@ -5889,6 -5920,8 +5920,8 @@@ static void haswell_crtc_disable(struc
        if (!transcoder_is_dsi(cpu_transcoder))
                intel_ddi_disable_transcoder_func(old_crtc_state);
  
+       intel_dsc_disable(old_crtc_state);
        if (INTEL_GEN(dev_priv) >= 9)
                skylake_scaler_disable(intel_crtc);
        else
  
        intel_encoders_post_disable(crtc, old_crtc_state, old_state);
  
-       if (INTEL_GEN(dev_priv) >= 11)
-               icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state);
        intel_encoders_post_pll_disable(crtc, old_crtc_state, old_state);
  }
  
@@@ -6724,7 -6754,7 +6754,7 @@@ static void compute_m_n(unsigned int m
  }
  
  void
- intel_link_compute_m_n(int bits_per_pixel, int nlanes,
+ intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
                       int pixel_clock, int link_clock,
                       struct intel_link_m_n *m_n,
                       bool constant_n)
@@@ -8939,7 -8969,7 +8969,7 @@@ skylake_get_initial_plane_config(struc
        fb->width = ((val >> 0) & 0x1fff) + 1;
  
        val = I915_READ(PLANE_STRIDE(pipe, plane_id));
-       stride_mult = intel_fb_stride_alignment(fb, 0);
+       stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
        fb->pitches[0] = (val & 0x3ff) * stride_mult;
  
        aligned_height = intel_fb_align_height(fb, 0, fb->height);
@@@ -9303,10 -9333,12 +9333,12 @@@ void hsw_disable_pc8(struct drm_i915_pr
  static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
                                      struct intel_crtc_state *crtc_state)
  {
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_atomic_state *state =
                to_intel_atomic_state(crtc_state->base.state);
  
-       if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) {
+       if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
+           IS_ICELAKE(dev_priv)) {
                struct intel_encoder *encoder =
                        intel_get_crtc_new_encoder(state, crtc_state);
  
@@@ -9444,11 -9476,18 +9476,18 @@@ static bool hsw_get_transcoder_state(st
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        enum intel_display_power_domain power_domain;
+       unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP);
+       unsigned long enabled_panel_transcoders = 0;
+       enum transcoder panel_transcoder;
        u32 tmp;
  
+       if (IS_ICELAKE(dev_priv))
+               panel_transcoder_mask |=
+                       BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
        /*
         * The pipe->transcoder mapping is fixed with the exception of the eDP
-        * transcoder handled below.
+        * and DSI transcoders handled below.
         */
        pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
  
         * XXX: Do intel_display_power_get_if_enabled before reading this (for
         * consistency and less surprising code; it's in always on power).
         */
-       tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
-       if (tmp & TRANS_DDI_FUNC_ENABLE) {
-               enum pipe trans_edp_pipe;
+       for_each_set_bit(panel_transcoder, &panel_transcoder_mask, 32) {
+               enum pipe trans_pipe;
+               tmp = I915_READ(TRANS_DDI_FUNC_CTL(panel_transcoder));
+               if (!(tmp & TRANS_DDI_FUNC_ENABLE))
+                       continue;
+               /*
+                * Log all enabled ones, only use the first one.
+                *
+                * FIXME: This won't work for two separate DSI displays.
+                */
+               enabled_panel_transcoders |= BIT(panel_transcoder);
+               if (enabled_panel_transcoders != BIT(panel_transcoder))
+                       continue;
                switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
                default:
-                       WARN(1, "unknown pipe linked to edp transcoder\n");
+                       WARN(1, "unknown pipe linked to transcoder %s\n",
+                            transcoder_name(panel_transcoder));
                        /* fall through */
                case TRANS_DDI_EDP_INPUT_A_ONOFF:
                case TRANS_DDI_EDP_INPUT_A_ON:
-                       trans_edp_pipe = PIPE_A;
+                       trans_pipe = PIPE_A;
                        break;
                case TRANS_DDI_EDP_INPUT_B_ONOFF:
-                       trans_edp_pipe = PIPE_B;
+                       trans_pipe = PIPE_B;
                        break;
                case TRANS_DDI_EDP_INPUT_C_ONOFF:
-                       trans_edp_pipe = PIPE_C;
+                       trans_pipe = PIPE_C;
                        break;
                }
  
-               if (trans_edp_pipe == crtc->pipe)
-                       pipe_config->cpu_transcoder = TRANSCODER_EDP;
+               if (trans_pipe == crtc->pipe)
+                       pipe_config->cpu_transcoder = panel_transcoder;
        }
  
+       /*
+        * Valid combos: none, eDP, DSI0, DSI1, DSI0+DSI1
+        */
+       WARN_ON((enabled_panel_transcoders & BIT(TRANSCODER_EDP)) &&
+               enabled_panel_transcoders != BIT(TRANSCODER_EDP));
        power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
@@@ -9611,7 -9670,8 +9670,8 @@@ static bool haswell_get_pipe_config(str
        if (!active)
                goto out;
  
-       if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+       if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+           IS_ICELAKE(dev_priv)) {
                haswell_get_ddi_port_state(crtc, pipe_config);
                intel_get_pipe_timings(crtc, pipe_config);
        }
@@@ -9667,7 -9727,7 +9727,7 @@@ static u32 intel_cursor_base(const stru
        const struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        u32 base;
  
-       if (INTEL_INFO(dev_priv)->cursor_needs_physical)
+       if (INTEL_INFO(dev_priv)->display.cursor_needs_physical)
                base = obj->phys_handle->busaddr;
        else
                base = intel_plane_ggtt_offset(plane_state);
@@@ -9894,9 -9954,9 +9954,9 @@@ static void i845_update_cursor(struct i
  }
  
  static void i845_disable_cursor(struct intel_plane *plane,
-                               struct intel_crtc *crtc)
+                               const struct intel_crtc_state *crtc_state)
  {
-       i845_update_cursor(plane, NULL, NULL);
+       i845_update_cursor(plane, crtc_state, NULL);
  }
  
  static bool i845_cursor_get_hw_state(struct intel_plane *plane,
@@@ -10087,8 -10147,8 +10147,8 @@@ static void i9xx_update_cursor(struct i
         * On some platforms writing CURCNTR first will also
         * cause CURPOS to be armed by the CURBASE write.
         * Without the CURCNTR write the CURPOS write would
-        * arm itself. Thus we always start the full update
-        * with a CURCNTR write.
+        * arm itself. Thus we always update CURCNTR before
+        * CURPOS.
         *
         * On other platforms CURPOS always requires the
         * CURBASE write to arm the update. Additonally
         * cursor that doesn't appear to move, or even change
         * shape. Thus we always write CURBASE.
         *
-        * CURCNTR and CUR_FBC_CTL are always
-        * armed by the CURBASE write only.
+        * The other registers are armed by by the CURBASE write
+        * except when the plane is getting enabled at which time
+        * the CURCNTR write arms the update.
         */
+       if (INTEL_GEN(dev_priv) >= 9)
+               skl_write_cursor_wm(plane, crtc_state);
        if (plane->cursor.base != base ||
            plane->cursor.size != fbc_ctl ||
            plane->cursor.cntl != cntl) {
-               I915_WRITE_FW(CURCNTR(pipe), cntl);
                if (HAS_CUR_FBC(dev_priv))
                        I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl);
+               I915_WRITE_FW(CURCNTR(pipe), cntl);
                I915_WRITE_FW(CURPOS(pipe), pos);
                I915_WRITE_FW(CURBASE(pipe), base);
  
  }
  
  static void i9xx_disable_cursor(struct intel_plane *plane,
-                               struct intel_crtc *crtc)
+                               const struct intel_crtc_state *crtc_state)
  {
-       i9xx_update_cursor(plane, NULL, NULL);
+       i9xx_update_cursor(plane, crtc_state, NULL);
  }
  
  static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
@@@ -10835,8 -10900,10 +10900,10 @@@ static int icl_check_nv12_planes(struc
                        continue;
  
                plane_state->linked_plane = NULL;
-               if (plane_state->slave && !plane_state->base.visible)
+               if (plane_state->slave && !plane_state->base.visible) {
                        crtc_state->active_planes &= ~BIT(plane->id);
+                       crtc_state->update_planes |= BIT(plane->id);
+               }
  
                plane_state->slave = false;
        }
                linked_state->slave = true;
                linked_state->linked_plane = plane;
                crtc_state->active_planes |= BIT(linked->id);
+               crtc_state->update_planes |= BIT(linked->id);
                DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
        }
  
@@@ -11887,6 -11955,8 +11955,8 @@@ static void verify_wm_state(struct drm_
        struct skl_pipe_wm hw_wm, *sw_wm;
        struct skl_plane_wm *hw_plane_wm, *sw_plane_wm;
        struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry;
+       struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES];
+       struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES];
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        const enum pipe pipe = intel_crtc->pipe;
        int plane, level, max_level = ilk_wm_max_level(dev_priv);
        skl_pipe_wm_get_hw_state(crtc, &hw_wm);
        sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal;
  
+       skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv);
        skl_ddb_get_hw_state(dev_priv, &hw_ddb);
        sw_ddb = &dev_priv->wm.skl_hw.ddb;
  
                }
  
                /* DDB */
-               hw_ddb_entry = &hw_ddb.plane[pipe][plane];
-               sw_ddb_entry = &sw_ddb->plane[pipe][plane];
+               hw_ddb_entry = &hw_ddb_y[plane];
+               sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane];
  
                if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
                        DRM_ERROR("mismatch in DDB state pipe %c plane %d (expected (%u,%u), found (%u,%u))\n",
                }
  
                /* DDB */
-               hw_ddb_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
-               sw_ddb_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+               hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR];
+               sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR];
  
                if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) {
                        DRM_ERROR("mismatch in DDB state pipe %c cursor (expected (%u,%u), found (%u,%u))\n",
@@@ -12623,10 -12695,6 +12695,10 @@@ static int intel_atomic_check(struct dr
                                       "[modeset]" : "[fastset]");
        }
  
 +      ret = drm_dp_mst_atomic_check(state);
 +      if (ret)
 +              return ret;
 +
        if (any_ms) {
                ret = intel_modeset_checks(state);
  
@@@ -12672,7 -12740,6 +12744,6 @@@ static void intel_update_crtc(struct dr
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_crtc_state *old_intel_cstate = to_intel_crtc_state(old_crtc_state);
        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_begin_crtc_commit(crtc, old_crtc_state);
  
-       intel_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc,
-                                   old_intel_cstate, pipe_config);
+       if (INTEL_GEN(dev_priv) >= 9)
+               skl_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc);
+       else
+               i9xx_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc);
  
        intel_finish_crtc_commit(crtc, old_crtc_state);
  }
@@@ -12889,7 -12958,7 +12962,7 @@@ static void intel_atomic_commit_tail(st
                intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state);
  
                if (old_crtc_state->active) {
-                       intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes);
+                       intel_crtc_disable_planes(intel_state, intel_crtc);
  
                        /*
                         * We need to disable pipe CRC before disabling the pipe,
@@@ -13244,7 -13313,7 +13317,7 @@@ static int intel_plane_pin_fb(struct in
        struct i915_vma *vma;
  
        if (plane->id == PLANE_CURSOR &&
-           INTEL_INFO(dev_priv)->cursor_needs_physical) {
+           INTEL_INFO(dev_priv)->display.cursor_needs_physical) {
                struct drm_i915_gem_object *obj = intel_fb_obj(fb);
                const int align = intel_cursor_alignment(dev_priv);
                int err;
@@@ -13739,7 -13808,7 +13812,7 @@@ intel_legacy_cursor_update(struct drm_p
                                          to_intel_plane_state(plane->state));
        } else {
                trace_intel_disable_plane(plane, to_intel_crtc(crtc));
-               intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
+               intel_plane->disable_plane(intel_plane, crtc_state);
        }
  
        intel_plane_unpin_fb(to_intel_plane_state(old_plane_state));
@@@ -14190,7 -14259,7 +14263,7 @@@ static void intel_setup_outputs(struct 
  
        intel_pps_init(dev_priv);
  
-       if (INTEL_INFO(dev_priv)->num_pipes == 0)
+       if (!HAS_DISPLAY(dev_priv))
                return;
  
        /*
@@@ -14455,7 -14524,6 +14528,6 @@@ static int intel_framebuffer_init(struc
  {
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        struct drm_framebuffer *fb = &intel_fb->base;
-       struct drm_format_name_buf format_name;
        u32 pitch_limit;
        unsigned int tiling, stride;
        int ret = -EINVAL;
                }
        }
  
-       /* Passed in modifier sanity checking. */
-       switch (mode_cmd->modifier[0]) {
-       case I915_FORMAT_MOD_Y_TILED_CCS:
-       case I915_FORMAT_MOD_Yf_TILED_CCS:
-               switch (mode_cmd->pixel_format) {
-               case DRM_FORMAT_XBGR8888:
-               case DRM_FORMAT_ABGR8888:
-               case DRM_FORMAT_XRGB8888:
-               case DRM_FORMAT_ARGB8888:
-                       break;
-               default:
-                       DRM_DEBUG_KMS("RC supported only with RGB8888 formats\n");
-                       goto err;
-               }
-               /* fall through */
-       case I915_FORMAT_MOD_Yf_TILED:
-               if (mode_cmd->pixel_format == DRM_FORMAT_C8) {
-                       DRM_DEBUG_KMS("Indexed format does not support Yf tiling\n");
-                       goto err;
-               }
-               /* fall through */
-       case I915_FORMAT_MOD_Y_TILED:
-               if (INTEL_GEN(dev_priv) < 9) {
-                       DRM_DEBUG_KMS("Unsupported tiling 0x%llx!\n",
-                                     mode_cmd->modifier[0]);
-                       goto err;
-               }
-               break;
-       case DRM_FORMAT_MOD_LINEAR:
-       case I915_FORMAT_MOD_X_TILED:
-               break;
-       default:
-               DRM_DEBUG_KMS("Unsupported fb modifier 0x%llx!\n",
+       if (!drm_any_plane_has_format(&dev_priv->drm,
+                                     mode_cmd->pixel_format,
+                                     mode_cmd->modifier[0])) {
+               struct drm_format_name_buf format_name;
+               DRM_DEBUG_KMS("unsupported pixel format %s / modifier 0x%llx\n",
+                             drm_get_format_name(mode_cmd->pixel_format,
+                                                 &format_name),
                              mode_cmd->modifier[0]);
                goto err;
        }
                goto err;
        }
  
-       /* Reject formats not supported by any plane early. */
-       switch (mode_cmd->pixel_format) {
-       case DRM_FORMAT_C8:
-       case DRM_FORMAT_RGB565:
-       case DRM_FORMAT_XRGB8888:
-       case DRM_FORMAT_ARGB8888:
-               break;
-       case DRM_FORMAT_XRGB1555:
-               if (INTEL_GEN(dev_priv) > 3) {
-                       DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                                     drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       goto err;
-               }
-               break;
-       case DRM_FORMAT_ABGR8888:
-               if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
-                   INTEL_GEN(dev_priv) < 9) {
-                       DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                                     drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       goto err;
-               }
-               break;
-       case DRM_FORMAT_XBGR8888:
-       case DRM_FORMAT_XRGB2101010:
-       case DRM_FORMAT_XBGR2101010:
-               if (INTEL_GEN(dev_priv) < 4) {
-                       DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                                     drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       goto err;
-               }
-               break;
-       case DRM_FORMAT_ABGR2101010:
-               if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
-                       DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                                     drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       goto err;
-               }
-               break;
-       case DRM_FORMAT_YUYV:
-       case DRM_FORMAT_UYVY:
-       case DRM_FORMAT_YVYU:
-       case DRM_FORMAT_VYUY:
-               if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv)) {
-                       DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                                     drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       goto err;
-               }
-               break;
-       case DRM_FORMAT_NV12:
-               if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) ||
-                   IS_BROXTON(dev_priv)) {
-                       DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                                     drm_get_format_name(mode_cmd->pixel_format,
-                                                         &format_name));
-                       goto err;
-               }
-               break;
-       default:
-               DRM_DEBUG_KMS("unsupported pixel format: %s\n",
-                             drm_get_format_name(mode_cmd->pixel_format, &format_name));
-               goto err;
-       }
        /* FIXME need to adjust LINOFF/TILEOFF accordingly. */
        if (mode_cmd->offsets[0] != 0)
                goto err;
@@@ -16070,7 -16050,7 +16054,7 @@@ intel_display_capture_error_state(struc
        };
        int i;
  
-       if (INTEL_INFO(dev_priv)->num_pipes == 0)
+       if (!HAS_DISPLAY(dev_priv))
                return NULL;
  
        error = kzalloc(sizeof(*error), GFP_ATOMIC);
index 153ee47d9c03de4dc9781277542f30cf4173388e,f94a04b4ad8788bcc1d8f9ca3073eaa00f33648a..a3252064b8d28a9f7487173f5a6dce6ba4302336
@@@ -706,6 -706,8 +706,8 @@@ struct intel_crtc_wm_state 
                        /* gen9+ only needs 1-step wm programming */
                        struct skl_pipe_wm optimal;
                        struct skl_ddb_entry ddb;
+                       struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
+                       struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES];
                } skl;
  
                struct {
@@@ -926,6 -928,9 +928,9 @@@ struct intel_crtc_state 
        u8 active_planes;
        u8 nv12_planes;
  
+       /* bitmask of planes that will be updated during the commit */
+       u8 update_planes;
        /* HDMI scrambling status */
        bool hdmi_scrambling;
  
  
        /* Output down scaling is done in LSPCON device */
        bool lspcon_downsampling;
+       /* Display Stream compression state */
+       struct {
+               bool compression_enable;
+               bool dsc_split;
+               u16 compressed_bpp;
+               u8 slice_count;
+       } dsc_params;
+       struct drm_dsc_config dp_dsc_cfg;
+       /* Forward Error correction State */
+       bool fec_enable;
  };
  
  struct intel_crtc {
@@@ -1013,7 -1030,7 +1030,7 @@@ struct intel_plane 
                             const struct intel_crtc_state *crtc_state,
                             const struct intel_plane_state *plane_state);
        void (*disable_plane)(struct intel_plane *plane,
-                             struct intel_crtc *crtc);
+                             const struct intel_crtc_state *crtc_state);
        bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
        int (*check_plane)(struct intel_crtc_state *crtc_state,
                           struct intel_plane_state *plane_state);
@@@ -1057,6 -1074,7 +1074,6 @@@ struct intel_hdmi 
        } dp_dual_mode;
        bool has_hdmi_sink;
        bool has_audio;
 -      bool rgb_quant_range_selectable;
        struct intel_connector *attached_connector;
        struct cec_notifier *cec_notifier;
  };
@@@ -1516,13 -1534,9 +1533,9 @@@ u8 intel_ddi_dp_pre_emphasis_max(struc
                                 u8 voltage_swing);
  int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
                                     bool enable);
- void icl_map_plls_to_ports(struct drm_crtc *crtc,
-                          struct intel_crtc_state *crtc_state,
-                          struct drm_atomic_state *old_state);
- void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
-                            struct intel_crtc_state *crtc_state,
-                            struct drm_atomic_state *old_state);
  void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
+ int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
+                       enum intel_dpll_id pll_id);
  
  unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
                                   int color_plane, unsigned int height);
@@@ -1787,6 -1801,9 +1800,9 @@@ void intel_dp_stop_link_train(struct in
  int intel_dp_retrain_link(struct intel_encoder *encoder,
                          struct drm_modeset_acquire_ctx *ctx);
  void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
+                                          const struct intel_crtc_state *crtc_state,
+                                          bool enable);
  void intel_dp_encoder_reset(struct drm_encoder *encoder);
  void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
  void intel_dp_encoder_destroy(struct drm_encoder *encoder);
@@@ -1842,6 -1859,12 +1858,12 @@@ uint16_t intel_dp_dsc_get_output_bpp(in
  uint8_t intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
                                     int mode_hdisplay);
  
+ /* intel_vdsc.c */
+ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
+                               struct intel_crtc_state *pipe_config);
+ enum intel_display_power_domain
+ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);
  static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
  {
        return ~((1 << lane_count) - 1) & 0xf;
@@@ -2046,6 -2069,7 +2068,7 @@@ void intel_psr_irq_handler(struct drm_i
  void intel_psr_short_pulse(struct intel_dp *intel_dp);
  int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
                            u32 *out_value);
+ bool intel_psr_enabled(struct intel_dp *intel_dp);
  
  /* intel_quirks.c */
  void intel_init_quirks(struct drm_i915_private *dev_priv);
@@@ -2180,6 -2204,9 +2203,9 @@@ void g4x_wm_get_hw_state(struct drm_dev
  void vlv_wm_get_hw_state(struct drm_device *dev);
  void ilk_wm_get_hw_state(struct drm_device *dev);
  void skl_wm_get_hw_state(struct drm_device *dev);
+ void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
+                              struct skl_ddb_entry *ddb_y,
+                              struct skl_ddb_entry *ddb_uv);
  void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
                          struct skl_ddb_allocation *ddb /* out */);
  void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc,
@@@ -2194,6 -2221,10 +2220,10 @@@ bool skl_wm_level_equals(const struct s
  bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
                                 const struct skl_ddb_entry entries[],
                                 int num_entries, int ignore_idx);
+ void skl_write_plane_wm(struct intel_plane *plane,
+                       const struct intel_crtc_state *crtc_state);
+ void skl_write_cursor_wm(struct intel_plane *plane,
+                        const struct intel_crtc_state *crtc_state);
  bool ilk_disable_lp_wm(struct drm_device *dev);
  int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
                                  struct intel_crtc_state *cstate);
@@@ -2286,10 -2317,10 +2316,10 @@@ struct drm_plane_state *intel_plane_dup
  void intel_plane_destroy_state(struct drm_plane *plane,
                               struct drm_plane_state *state);
  extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
- void intel_update_planes_on_crtc(struct intel_atomic_state *old_state,
-                                struct intel_crtc *crtc,
                               struct intel_crtc_state *old_crtc_state,
-                                struct intel_crtc_state *new_crtc_state);
+ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
+                              struct intel_crtc *crtc);
void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
+                               struct intel_crtc *crtc);
  int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
                                        struct intel_crtc_state *crtc_state,
                                        const struct intel_plane_state *old_plane_state,
index 4d264e577e3b25fa11ee8dc1b3a4d07087aebfc2,07e803a604bddada573810e15eef3c01975a9dd8..55aeb97dd66df37ca3147498d301febe19ed8b69
@@@ -115,6 -115,8 +115,8 @@@ static u32 hsw_infoframe_enable(unsigne
        switch (type) {
        case DP_SDP_VSC:
                return VIDEO_DIP_ENABLE_VSC_HSW;
+       case DP_SDP_PPS:
+               return VDIP_ENABLE_PPS;
        case HDMI_INFOFRAME_TYPE_AVI:
                return VIDEO_DIP_ENABLE_AVI_HSW;
        case HDMI_INFOFRAME_TYPE_SPD:
@@@ -136,6 -138,8 +138,8 @@@ hsw_dip_data_reg(struct drm_i915_privat
        switch (type) {
        case DP_SDP_VSC:
                return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i);
+       case DP_SDP_PPS:
+               return ICL_VIDEO_DIP_PPS_DATA(cpu_transcoder, i);
        case HDMI_INFOFRAME_TYPE_AVI:
                return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i);
        case HDMI_INFOFRAME_TYPE_SPD:
        }
  }
  
+ static int hsw_dip_data_size(unsigned int type)
+ {
+       switch (type) {
+       case DP_SDP_VSC:
+               return VIDEO_DIP_VSC_DATA_SIZE;
+       case DP_SDP_PPS:
+               return VIDEO_DIP_PPS_DATA_SIZE;
+       default:
+               return VIDEO_DIP_DATA_SIZE;
+       }
+ }
  static void g4x_write_infoframe(struct intel_encoder *encoder,
                                const struct intel_crtc_state *crtc_state,
                                unsigned int type,
@@@ -382,11 -398,12 +398,12 @@@ static void hsw_write_infoframe(struct 
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
-       int data_size = type == DP_SDP_VSC ?
-               VIDEO_DIP_VSC_DATA_SIZE : VIDEO_DIP_DATA_SIZE;
+       int data_size;
        int i;
        u32 val = I915_READ(ctl_reg);
  
+       data_size = hsw_dip_data_size(type);
        val &= ~hsw_infoframe_enable(type);
        I915_WRITE(ctl_reg, val);
  
@@@ -462,14 -479,18 +479,14 @@@ static void intel_hdmi_set_avi_infofram
                                         const struct intel_crtc_state *crtc_state,
                                         const struct drm_connector_state *conn_state)
  {
 -      struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->base.adjusted_mode;
 -      struct drm_connector *connector = &intel_hdmi->attached_connector->base;
 -      bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported ||
 -         connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
        union hdmi_infoframe frame;
        int ret;
  
        ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
 -                                                     adjusted_mode,
 -                                                     is_hdmi2_sink);
 +                                                     conn_state->connector,
 +                                                     adjusted_mode);
        if (ret < 0) {
                DRM_ERROR("couldn't fill AVI infoframe\n");
                return;
        else
                frame.avi.colorspace = HDMI_COLORSPACE_RGB;
  
 -      drm_hdmi_avi_infoframe_quant_range(&frame.avi, adjusted_mode,
 +      drm_hdmi_avi_infoframe_quant_range(&frame.avi,
 +                                         conn_state->connector,
 +                                         adjusted_mode,
                                           crtc_state->limited_color_range ?
                                           HDMI_QUANTIZATION_RANGE_LIMITED :
 -                                         HDMI_QUANTIZATION_RANGE_FULL,
 -                                         intel_hdmi->rgb_quant_range_selectable,
 -                                         is_hdmi2_sink);
 +                                         HDMI_QUANTIZATION_RANGE_FULL);
  
        drm_hdmi_avi_infoframe_content_type(&frame.avi,
                                            conn_state);
@@@ -1814,6 -1835,7 +1831,6 @@@ intel_hdmi_unset_edid(struct drm_connec
  
        intel_hdmi->has_hdmi_sink = false;
        intel_hdmi->has_audio = false;
 -      intel_hdmi->rgb_quant_range_selectable = false;
  
        intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
        intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
@@@ -1897,6 -1919,9 +1914,6 @@@ intel_hdmi_set_edid(struct drm_connecto
  
        to_intel_connector(connector)->detect_edid = edid;
        if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 -              intel_hdmi->rgb_quant_range_selectable =
 -                      drm_rgb_quant_range_selectable(edid);
 -
                intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
                intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
  
index 0b6c29cdd9349b76b00acd444c6c3618075a376e,807111ebfdd97785ac2b6855a1af14dc5067a8f9..bc25001b820759dc1d3e1e56c27fa813d29732d9
@@@ -365,7 -365,7 +365,7 @@@ static int dw_hdmi_phy_init(struct dw_h
        unsigned int wr_clk =
                readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING));
  
 -      DRM_DEBUG_DRIVER("%d:\"%s\"\n", mode->base.id, mode->name);
 +      DRM_DEBUG_DRIVER("\"%s\"\n", mode->name);
  
        /* Enable clocks */
        regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
@@@ -555,7 -555,12 +555,7 @@@ dw_hdmi_mode_valid(struct drm_connecto
        int vic = drm_match_cea_mode(mode);
        enum drm_mode_status status;
  
 -      DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
 -              mode->base.id, mode->name, mode->vrefresh, mode->clock,
 -              mode->hdisplay, mode->hsync_start,
 -              mode->hsync_end, mode->htotal,
 -              mode->vdisplay, mode->vsync_start,
 -              mode->vsync_end, mode->vtotal, mode->type, mode->flags);
 +      DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
  
        /* Check against non-VIC supported modes */
        if (!vic) {
@@@ -645,7 -650,8 +645,7 @@@ static void meson_venc_hdmi_encoder_mod
        struct meson_drm *priv = dw_hdmi->priv;
        int vic = drm_match_cea_mode(mode);
  
 -      DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n",
 -                       mode->base.id, mode->name, vic);
 +      DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic);
  
        /* VENC + VENC-DVI Mode setup */
        meson_venc_hdmi_mode_set(priv, vic, mode);
@@@ -690,6 -696,7 +690,7 @@@ static const struct regmap_config meson
        .reg_read = meson_dw_hdmi_reg_read,
        .reg_write = meson_dw_hdmi_reg_write,
        .max_register = 0x10000,
+       .fast_io = true,
  };
  
  static bool meson_hdmi_connector_is_available(struct device *dev)
index 7b028f778960606fd4ab64ef0f542835a5a6bfb8,8f2359dc87b4ea5b34aabe77bb288a365f5f3233..cc32ea5f4289eca3ecea7ddf889ea78f13e84e90
@@@ -128,7 -128,7 +128,7 @@@ static void unref_cursor_worker(struct 
        struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base);
        struct msm_kms *kms = &mdp4_kms->base.base;
  
-       msm_gem_put_iova(val, kms->aspace);
+       msm_gem_unpin_iova(val, kms->aspace);
        drm_gem_object_put_unlocked(val);
  }
  
@@@ -244,8 -244,14 +244,8 @@@ static void mdp4_crtc_mode_set_nofb(str
  
        mode = &crtc->state->adjusted_mode;
  
 -      DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
 -                      mdp4_crtc->name, mode->base.id, mode->name,
 -                      mode->vrefresh, mode->clock,
 -                      mode->hdisplay, mode->hsync_start,
 -                      mode->hsync_end, mode->htotal,
 -                      mode->vdisplay, mode->vsync_start,
 -                      mode->vsync_end, mode->vtotal,
 -                      mode->type, mode->flags);
 +      DBG("%s: set mode: " DRM_MODE_FMT,
 +                      mdp4_crtc->name, DRM_MODE_ARG(mode));
  
        mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
                        MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
@@@ -378,7 -384,7 +378,7 @@@ static void update_cursor(struct drm_cr
                if (next_bo) {
                        /* take a obj ref + iova ref when we start scanning out: */
                        drm_gem_object_get(next_bo);
-                       msm_gem_get_iova(next_bo, kms->aspace, &iova);
+                       msm_gem_get_and_pin_iova(next_bo, kms->aspace, &iova);
  
                        /* enable cursor: */
                        mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma),
@@@ -423,7 -429,7 +423,7 @@@ static int mdp4_crtc_cursor_set(struct 
        int ret;
  
        if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
-               dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
+               DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height);
                return -EINVAL;
        }
  
        }
  
        if (cursor_bo) {
-               ret = msm_gem_get_iova(cursor_bo, kms->aspace, &iova);
+               ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &iova);
                if (ret)
                        goto fail;
        } else {
index f6bc86a35d8d76dca726a975181fcde699c0751d,a8fd14d4846b37d95160b6b00ea84c32a270c2bc..ff8f2da160c0c15308aec3a931da6147f05ef8eb
@@@ -45,7 -45,7 +45,7 @@@ static void bs_init(struct mdp4_dtv_enc
        struct lcdc_platform_data *dtv_pdata = mdp4_find_pdata("dtv.0");
  
        if (!dtv_pdata) {
-               dev_err(dev->dev, "could not find dtv pdata\n");
+               DRM_DEV_ERROR(dev->dev, "could not find dtv pdata\n");
                return;
        }
  
@@@ -104,7 -104,14 +104,7 @@@ static void mdp4_dtv_encoder_mode_set(s
  
        mode = adjusted_mode;
  
 -      DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
 -                      mode->base.id, mode->name,
 -                      mode->vrefresh, mode->clock,
 -                      mode->hdisplay, mode->hsync_start,
 -                      mode->hsync_end, mode->htotal,
 -                      mode->vdisplay, mode->vsync_start,
 -                      mode->vsync_end, mode->vtotal,
 -                      mode->type, mode->flags);
 +      DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
  
        mdp4_dtv_encoder->pixclock = mode->clock * 1000;
  
@@@ -202,16 -209,16 +202,16 @@@ static void mdp4_dtv_encoder_enable(str
  
        ret = clk_set_rate(mdp4_dtv_encoder->mdp_clk, pc);
        if (ret)
-               dev_err(dev->dev, "failed to set mdp_clk to %lu: %d\n",
+               DRM_DEV_ERROR(dev->dev, "failed to set mdp_clk to %lu: %d\n",
                        pc, ret);
  
        ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk);
        if (ret)
-               dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
  
        ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk);
        if (ret)
-               dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
  
        mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1);
  
@@@ -251,14 -258,14 +251,14 @@@ struct drm_encoder *mdp4_dtv_encoder_in
  
        mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk");
        if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) {
-               dev_err(dev->dev, "failed to get hdmi_clk\n");
+               DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n");
                ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk);
                goto fail;
        }
  
        mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk");
        if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) {
-               dev_err(dev->dev, "failed to get tv_clk\n");
+               DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n");
                ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk);
                goto fail;
        }
index d47b8f4af991357bc6824590f3e742f2fe5b9036,c9e34501a89e8c485743b8a27632783bde4355bb..fff77a4b12c2d15fdc30f9049f852672cf076c20
@@@ -47,7 -47,7 +47,7 @@@ static void bs_init(struct mdp4_lcdc_en
        struct lcdc_platform_data *lcdc_pdata = mdp4_find_pdata("lvds.0");
  
        if (!lcdc_pdata) {
-               dev_err(dev->dev, "could not find lvds pdata\n");
+               DRM_DEV_ERROR(dev->dev, "could not find lvds pdata\n");
                return;
        }
  
@@@ -224,7 -224,7 +224,7 @@@ static void setup_phy(struct drm_encode
                break;
  
        default:
-               dev_err(dev->dev, "unknown bpp: %d\n", bpp);
+               DRM_DEV_ERROR(dev->dev, "unknown bpp: %d\n", bpp);
                return;
        }
  
                                MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN;
                break;
        default:
-               dev_err(dev->dev, "unknown # of channels: %d\n", nchan);
+               DRM_DEV_ERROR(dev->dev, "unknown # of channels: %d\n", nchan);
                return;
        }
  
@@@ -273,7 -273,14 +273,7 @@@ static void mdp4_lcdc_encoder_mode_set(
  
        mode = adjusted_mode;
  
 -      DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
 -                      mode->base.id, mode->name,
 -                      mode->vrefresh, mode->clock,
 -                      mode->hdisplay, mode->hsync_start,
 -                      mode->hsync_end, mode->htotal,
 -                      mode->vdisplay, mode->vsync_start,
 -                      mode->vsync_end, mode->vtotal,
 -                      mode->type, mode->flags);
 +      DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
  
        mdp4_lcdc_encoder->pixclock = mode->clock * 1000;
  
@@@ -354,7 -361,7 +354,7 @@@ static void mdp4_lcdc_encoder_disable(s
        for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
                ret = regulator_disable(mdp4_lcdc_encoder->regs[i]);
                if (ret)
-                       dev_err(dev->dev, "failed to disable regulator: %d\n", ret);
+                       DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret);
        }
  
        bs_set(mdp4_lcdc_encoder, 0);
@@@ -370,20 -377,25 +370,25 @@@ static void mdp4_lcdc_encoder_enable(st
        unsigned long pc = mdp4_lcdc_encoder->pixclock;
        struct mdp4_kms *mdp4_kms = get_kms(encoder);
        struct drm_panel *panel;
+       uint32_t config;
        int i, ret;
  
        if (WARN_ON(mdp4_lcdc_encoder->enabled))
                return;
  
        /* TODO: hard-coded for 18bpp: */
-       mdp4_crtc_set_config(encoder->crtc,
-                       MDP4_DMA_CONFIG_R_BPC(BPC6) |
-                       MDP4_DMA_CONFIG_G_BPC(BPC6) |
-                       MDP4_DMA_CONFIG_B_BPC(BPC6) |
-                       MDP4_DMA_CONFIG_PACK_ALIGN_MSB |
-                       MDP4_DMA_CONFIG_PACK(0x21) |
-                       MDP4_DMA_CONFIG_DEFLKR_EN |
-                       MDP4_DMA_CONFIG_DITHER_EN);
+       config =
+               MDP4_DMA_CONFIG_R_BPC(BPC6) |
+               MDP4_DMA_CONFIG_G_BPC(BPC6) |
+               MDP4_DMA_CONFIG_B_BPC(BPC6) |
+               MDP4_DMA_CONFIG_PACK(0x21) |
+               MDP4_DMA_CONFIG_DEFLKR_EN |
+               MDP4_DMA_CONFIG_DITHER_EN;
+       if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb"))
+               config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB;
+       mdp4_crtc_set_config(encoder->crtc, config);
        mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
  
        bs_set(mdp4_lcdc_encoder, 1);
        for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
                ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
                if (ret)
-                       dev_err(dev->dev, "failed to enable regulator: %d\n", ret);
+                       DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret);
        }
  
        DBG("setting lcdc_clk=%lu", pc);
        ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
        if (ret)
-               dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
        ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
        if (ret)
-               dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
  
        panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
        if (!IS_ERR(panel)) {
@@@ -454,7 -466,7 +459,7 @@@ struct drm_encoder *mdp4_lcdc_encoder_i
        /* TODO: do we need different pll in other cases? */
        mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev);
        if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) {
-               dev_err(dev->dev, "failed to get lvds_clk\n");
+               DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n");
                ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk);
                goto fail;
        }
        reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v");
        if (IS_ERR(reg)) {
                ret = PTR_ERR(reg);
-               dev_err(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret);
                goto fail;
        }
        mdp4_lcdc_encoder->regs[0] = reg;
        reg = devm_regulator_get(dev->dev, "lvds-pll-vdda");
        if (IS_ERR(reg)) {
                ret = PTR_ERR(reg);
-               dev_err(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret);
                goto fail;
        }
        mdp4_lcdc_encoder->regs[1] = reg;
        reg = devm_regulator_get(dev->dev, "lvds-vdda");
        if (IS_ERR(reg)) {
                ret = PTR_ERR(reg);
-               dev_err(dev->dev, "failed to get lvds-vdda: %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret);
                goto fail;
        }
        mdp4_lcdc_encoder->regs[2] = reg;
index 33972c1816ed85c346ad2ccee0e873f5376036b5,c1962f29ec7d688e98ec57f40c9375210fc47af0..976585d8bfd631aed30299633345f307b0e04908
@@@ -55,20 -55,20 +55,20 @@@ static int pingpong_tearcheck_setup(str
        int pp_id = mixer->pp;
  
        if (IS_ERR_OR_NULL(mdp5_kms->vsync_clk)) {
-               dev_err(dev, "vsync_clk is not initialized\n");
+               DRM_DEV_ERROR(dev, "vsync_clk is not initialized\n");
                return -EINVAL;
        }
  
        total_lines_x100 = mode->vtotal * mode->vrefresh;
        if (!total_lines_x100) {
-               dev_err(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
+               DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
                                __func__, mode->vtotal, mode->vrefresh);
                return -EINVAL;
        }
  
        vsync_clk_speed = clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE);
        if (vsync_clk_speed <= 0) {
-               dev_err(dev, "vsync_clk round rate failed %ld\n",
+               DRM_DEV_ERROR(dev, "vsync_clk round rate failed %ld\n",
                                                        vsync_clk_speed);
                return -EINVAL;
        }
@@@ -102,13 -102,13 +102,13 @@@ static int pingpong_tearcheck_enable(st
        ret = clk_set_rate(mdp5_kms->vsync_clk,
                clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE));
        if (ret) {
-               dev_err(encoder->dev->dev,
+               DRM_DEV_ERROR(encoder->dev->dev,
                        "vsync_clk clk_set_rate failed, %d\n", ret);
                return ret;
        }
        ret = clk_prepare_enable(mdp5_kms->vsync_clk);
        if (ret) {
-               dev_err(encoder->dev->dev,
+               DRM_DEV_ERROR(encoder->dev->dev,
                        "vsync_clk clk_prepare_enable failed, %d\n", ret);
                return ret;
        }
@@@ -134,7 -134,14 +134,7 @@@ void mdp5_cmd_encoder_mode_set(struct d
  {
        mode = adjusted_mode;
  
 -      DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
 -                      mode->base.id, mode->name,
 -                      mode->vrefresh, mode->clock,
 -                      mode->hdisplay, mode->hsync_start,
 -                      mode->hsync_end, mode->htotal,
 -                      mode->vdisplay, mode->vsync_start,
 -                      mode->vsync_end, mode->vtotal,
 -                      mode->type, mode->flags);
 +      DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
        pingpong_tearcheck_setup(encoder, mode);
        mdp5_crtc_set_pipeline(encoder->crtc);
  }
index 4878b81c96fb796526fe32ffff1e82e839605e98,c5fde1a4191aaa03d7a002e52b803a2689519667..2f95e65255896739f448ddfcfc7cacac85793759
@@@ -173,7 -173,7 +173,7 @@@ static void unref_cursor_worker(struct 
        struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
        struct msm_kms *kms = &mdp5_kms->base.base;
  
-       msm_gem_put_iova(val, kms->aspace);
+       msm_gem_unpin_iova(val, kms->aspace);
        drm_gem_object_put_unlocked(val);
  }
  
@@@ -384,7 -384,14 +384,7 @@@ static void mdp5_crtc_mode_set_nofb(str
  
        mode = &crtc->state->adjusted_mode;
  
 -      DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
 -                      crtc->name, mode->base.id, mode->name,
 -                      mode->vrefresh, mode->clock,
 -                      mode->hdisplay, mode->hsync_start,
 -                      mode->hsync_end, mode->htotal,
 -                      mode->vdisplay, mode->vsync_start,
 -                      mode->vsync_end, mode->vtotal,
 -                      mode->type, mode->flags);
 +      DBG("%s: set mode: " DRM_MODE_FMT, crtc->name, DRM_MODE_ARG(mode));
  
        mixer_width = mode->hdisplay;
        if (r_mixer)
@@@ -655,7 -662,7 +655,7 @@@ static int mdp5_crtc_atomic_check(struc
  
        ret = mdp5_crtc_setup_pipeline(crtc, state, need_right_mixer);
        if (ret) {
-               dev_err(dev->dev, "couldn't assign mixers %d\n", ret);
+               DRM_DEV_ERROR(dev->dev, "couldn't assign mixers %d\n", ret);
                return ret;
        }
  
         * and that we don't have conflicting mixer stages:
         */
        if ((cnt + start - 1) >= hw_cfg->lm.nb_stages) {
-               dev_err(dev->dev, "too many planes! cnt=%d, start stage=%d\n",
+               DRM_DEV_ERROR(dev->dev, "too many planes! cnt=%d, start stage=%d\n",
                        cnt, start);
                return -EINVAL;
        }
@@@ -872,7 -879,7 +872,7 @@@ static int mdp5_crtc_cursor_set(struct 
        }
  
        if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
-               dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
+               DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height);
                return -EINVAL;
        }
  
        if (!cursor_bo)
                return -ENOENT;
  
-       ret = msm_gem_get_iova(cursor_bo, kms->aspace,
+       ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace,
                        &mdp5_crtc->cursor.iova);
        if (ret)
                return -EINVAL;
  set_cursor:
        ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable);
        if (ret) {
-               dev_err(dev->dev, "failed to %sable cursor: %d\n",
+               DRM_DEV_ERROR(dev->dev, "failed to %sable cursor: %d\n",
                                cursor_enable ? "en" : "dis", ret);
                goto end;
        }
index 5ed4cab2819f5a77edbf2718a0bae1880862909a,98d61c690260f49a09228c75ee325738ed484aa5..7ba6f52ed72cc76610695ea3dae8d99b4150c4ef
@@@ -40,7 -40,7 +40,7 @@@ static void msm_hdmi_power_on(struct dr
        for (i = 0; i < config->pwr_reg_cnt; i++) {
                ret = regulator_enable(hdmi->pwr_regs[i]);
                if (ret) {
-                       dev_err(dev->dev, "failed to enable pwr regulator: %s (%d)\n",
+                       DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %s (%d)\n",
                                        config->pwr_reg_names[i], ret);
                }
        }
@@@ -49,7 -49,7 +49,7 @@@
                DBG("pixclock: %lu", hdmi->pixclock);
                ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock);
                if (ret) {
-                       dev_err(dev->dev, "failed to set pixel clk: %s (%d)\n",
+                       DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s (%d)\n",
                                        config->pwr_clk_names[0], ret);
                }
        }
@@@ -57,7 -57,7 +57,7 @@@
        for (i = 0; i < config->pwr_clk_cnt; i++) {
                ret = clk_prepare_enable(hdmi->pwr_clks[i]);
                if (ret) {
-                       dev_err(dev->dev, "failed to enable pwr clk: %s (%d)\n",
+                       DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s (%d)\n",
                                        config->pwr_clk_names[i], ret);
                }
        }
@@@ -82,7 -82,7 +82,7 @@@ static void power_off(struct drm_bridg
        for (i = 0; i < config->pwr_reg_cnt; i++) {
                ret = regulator_disable(hdmi->pwr_regs[i]);
                if (ret) {
-                       dev_err(dev->dev, "failed to disable pwr regulator: %s (%d)\n",
+                       DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %s (%d)\n",
                                        config->pwr_reg_names[i], ret);
                }
        }
@@@ -101,12 -101,11 +101,12 @@@ static void msm_hdmi_config_avi_infofra
        u32 val;
        int len;
  
 -      drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
 +      drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
 +                                               hdmi->connector, mode);
  
        len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer));
        if (len < 0) {
-               dev_err(&hdmi->pdev->dev,
+               DRM_DEV_ERROR(&hdmi->pdev->dev,
                        "failed to configure avi infoframe\n");
                return;
        }
index 500bf3e0f6f2e9b7db7800005206f2fe318cdb89,26af4578593916d7700836d7810de18652c0abe6..67107f0b129927eacad628c27a10e57d37b73385
@@@ -198,6 -198,22 +198,22 @@@ nv50_dmac_create(struct nvif_device *de
  /******************************************************************************
   * EVO channel helpers
   *****************************************************************************/
+ static void
+ evo_flush(struct nv50_dmac *dmac)
+ {
+       /* Push buffer fetches are not coherent with BAR1, we need to ensure
+        * writes have been flushed right through to VRAM before writing PUT.
+        */
+       if (dmac->push.type & NVIF_MEM_VRAM) {
+               struct nvif_device *device = dmac->base.device;
+               nvif_wr32(&device->object, 0x070000, 0x00000001);
+               nvif_msec(device, 2000,
+                       if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
+                               break;
+               );
+       }
+ }
  u32 *
  evo_wait(struct nv50_dmac *evoc, int nr)
  {
        mutex_lock(&dmac->lock);
        if (put + nr >= (PAGE_SIZE / 4) - 8) {
                dmac->ptr[put] = 0x20000000;
+               evo_flush(dmac);
  
                nvif_wr32(&dmac->base.user, 0x0000, 0x00000000);
                if (nvif_msec(device, 2000,
@@@ -230,17 -247,7 +247,7 @@@ evo_kick(u32 *push, struct nv50_dmac *e
  {
        struct nv50_dmac *dmac = evoc;
  
-       /* Push buffer fetches are not coherent with BAR1, we need to ensure
-        * writes have been flushed right through to VRAM before writing PUT.
-        */
-       if (dmac->push.type & NVIF_MEM_VRAM) {
-               struct nvif_device *device = dmac->base.device;
-               nvif_wr32(&device->object, 0x070000, 0x00000001);
-               nvif_msec(device, 2000,
-                       if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
-                               break;
-               );
-       }
+       evo_flush(dmac);
  
        nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2);
        mutex_unlock(&dmac->lock);
@@@ -554,7 -561,7 +561,7 @@@ nv50_hdmi_enable(struct drm_encoder *en
        u32 max_ac_packet;
        union hdmi_infoframe avi_frame;
        union hdmi_infoframe vendor_frame;
 -      bool scdc_supported, high_tmds_clock_ratio = false, scrambling = false;
 +      bool high_tmds_clock_ratio = false, scrambling = false;
        u8 config;
        int ret;
        int size;
                return;
  
        hdmi = &nv_connector->base.display_info.hdmi;
 -      scdc_supported = hdmi->scdc.supported;
  
 -      ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode,
 -                                                     scdc_supported);
 +      ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi,
 +                                                     &nv_connector->base, mode);
        if (!ret) {
                /* We have an AVI InfoFrame, populate it to the display */
                args.pwr.avi_infoframe_length
@@@ -672,8 -680,6 +679,8 @@@ nv50_msto_payload(struct nv50_msto *mst
        struct nv50_mstm *mstm = mstc->mstm;
        int vcpi = mstc->port->vcpi.vcpi, i;
  
 +      WARN_ON(!mutex_is_locked(&mstm->mgr.payload_lock));
 +
        NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi);
        for (i = 0; i < mstm->mgr.max_payloads; i++) {
                struct drm_dp_payload *payload = &mstm->mgr.payloads[i];
@@@ -698,16 -704,14 +705,16 @@@ nv50_msto_cleanup(struct nv50_msto *mst
        struct nv50_mstc *mstc = msto->mstc;
        struct nv50_mstm *mstm = mstc->mstm;
  
 +      if (!msto->disabled)
 +              return;
 +
        NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 -      if (mstc->port && mstc->port->vcpi.vcpi > 0 && !nv50_msto_payload(msto))
 -              drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
 -      if (msto->disabled) {
 -              msto->mstc = NULL;
 -              msto->head = NULL;
 -              msto->disabled = false;
 -      }
 +
 +      drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
 +
 +      msto->mstc = NULL;
 +      msto->head = NULL;
 +      msto->disabled = false;
  }
  
  static void
@@@ -727,10 -731,8 +734,10 @@@ nv50_msto_prepare(struct nv50_msto *mst
                               (0x0100 << msto->head->base.index),
        };
  
 +      mutex_lock(&mstm->mgr.payload_lock);
 +
        NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
 -      if (mstc->port && mstc->port->vcpi.vcpi > 0) {
 +      if (mstc->port->vcpi.vcpi > 0) {
                struct drm_dp_payload *payload = nv50_msto_payload(msto);
                if (payload) {
                        args.vcpi.start_slot = payload->start_slot;
                  msto->encoder.name, msto->head->base.base.name,
                  args.vcpi.start_slot, args.vcpi.num_slots,
                  args.vcpi.pbn, args.vcpi.aligned_pbn);
 +
        nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args));
 +      mutex_unlock(&mstm->mgr.payload_lock);
  }
  
  static int
@@@ -754,23 -754,16 +761,23 @@@ nv50_msto_atomic_check(struct drm_encod
                       struct drm_crtc_state *crtc_state,
                       struct drm_connector_state *conn_state)
  {
 -      struct nv50_mstc *mstc = nv50_mstc(conn_state->connector);
 +      struct drm_atomic_state *state = crtc_state->state;
 +      struct drm_connector *connector = conn_state->connector;
 +      struct nv50_mstc *mstc = nv50_mstc(connector);
        struct nv50_mstm *mstm = mstc->mstm;
 -      int bpp = conn_state->connector->display_info.bpc * 3;
 +      int bpp = connector->display_info.bpc * 3;
        int slots;
  
 -      mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, bpp);
 +      mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
 +                                       bpp);
  
 -      slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn);
 -      if (slots < 0)
 -              return slots;
 +      if (drm_atomic_crtc_needs_modeset(crtc_state) &&
 +          !drm_connector_is_unregistered(connector)) {
 +              slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
 +                                                    mstc->port, mstc->pbn);
 +              if (slots < 0)
 +                      return slots;
 +      }
  
        return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
                                           mstc->native);
@@@ -836,7 -829,8 +843,7 @@@ nv50_msto_disable(struct drm_encoder *e
        struct nv50_mstc *mstc = msto->mstc;
        struct nv50_mstm *mstm = mstc->mstm;
  
 -      if (mstc->port)
 -              drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port);
 +      drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port);
  
        mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0);
        mstm->modified = true;
@@@ -933,43 -927,12 +940,43 @@@ nv50_mstc_get_modes(struct drm_connecto
        return ret;
  }
  
 +static int
 +nv50_mstc_atomic_check(struct drm_connector *connector,
 +                     struct drm_connector_state *new_conn_state)
 +{
 +      struct drm_atomic_state *state = new_conn_state->state;
 +      struct nv50_mstc *mstc = nv50_mstc(connector);
 +      struct drm_dp_mst_topology_mgr *mgr = &mstc->mstm->mgr;
 +      struct drm_connector_state *old_conn_state =
 +              drm_atomic_get_old_connector_state(state, connector);
 +      struct drm_crtc_state *crtc_state;
 +      struct drm_crtc *new_crtc = new_conn_state->crtc;
 +
 +      if (!old_conn_state->crtc)
 +              return 0;
 +
 +      /* We only want to free VCPI if this state disables the CRTC on this
 +       * connector
 +       */
 +      if (new_crtc) {
 +              crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
 +
 +              if (!crtc_state ||
 +                  !drm_atomic_crtc_needs_modeset(crtc_state) ||
 +                  crtc_state->enable)
 +                      return 0;
 +      }
 +
 +      return drm_dp_atomic_release_vcpi_slots(state, mgr, mstc->port);
 +}
 +
  static const struct drm_connector_helper_funcs
  nv50_mstc_help = {
        .get_modes = nv50_mstc_get_modes,
        .mode_valid = nv50_mstc_mode_valid,
        .best_encoder = nv50_mstc_best_encoder,
        .atomic_best_encoder = nv50_mstc_atomic_best_encoder,
 +      .atomic_check = nv50_mstc_atomic_check,
  };
  
  static enum drm_connector_status
@@@ -979,7 -942,7 +986,7 @@@ nv50_mstc_detect(struct drm_connector *
        enum drm_connector_status conn_status;
        int ret;
  
 -      if (!mstc->port)
 +      if (drm_connector_is_unregistered(connector))
                return connector_status_disconnected;
  
        ret = pm_runtime_get_sync(connector->dev->dev);
@@@ -998,10 -961,7 +1005,10 @@@ static voi
  nv50_mstc_destroy(struct drm_connector *connector)
  {
        struct nv50_mstc *mstc = nv50_mstc(connector);
 +
        drm_connector_cleanup(&mstc->connector);
 +      drm_dp_mst_put_port_malloc(mstc->port);
 +
        kfree(mstc);
  }
  
@@@ -1049,7 -1009,6 +1056,7 @@@ nv50_mstc_new(struct nv50_mstm *mstm, s
        drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
        drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0);
        drm_connector_set_path_property(&mstc->connector, path);
 +      drm_dp_mst_get_port_malloc(port);
        return 0;
  }
  
@@@ -1114,6 -1073,10 +1121,6 @@@ nv50_mstm_destroy_connector(struct drm_
  
        drm_fb_helper_remove_one_connector(&drm->fbcon->helper, &mstc->connector);
  
 -      drm_modeset_lock(&drm->dev->mode_config.connection_mutex, NULL);
 -      mstc->port = NULL;
 -      drm_modeset_unlock(&drm->dev->mode_config.connection_mutex);
 -
        drm_connector_put(&mstc->connector);
  }
  
@@@ -1136,8 -1099,11 +1143,8 @@@ nv50_mstm_add_connector(struct drm_dp_m
        int ret;
  
        ret = nv50_mstc_new(mstm, port, path, &mstc);
 -      if (ret) {
 -              if (mstc)
 -                      mstc->connector.funcs->destroy(&mstc->connector);
 +      if (ret)
                return NULL;
 -      }
  
        return &mstc->connector;
  }
@@@ -1288,8 -1254,16 +1295,16 @@@ nv50_mstm_fini(struct nv50_mstm *mstm
  static void
  nv50_mstm_init(struct nv50_mstm *mstm)
  {
-       if (mstm && mstm->mgr.mst_state)
-               drm_dp_mst_topology_mgr_resume(&mstm->mgr);
+       int ret;
+       if (!mstm || !mstm->mgr.mst_state)
+               return;
+       ret = drm_dp_mst_topology_mgr_resume(&mstm->mgr);
+       if (ret == -1) {
+               drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false);
+               drm_kms_helper_hotplug_event(mstm->mgr.dev);
+       }
  }
  
  static void
@@@ -1297,6 -1271,7 +1312,7 @@@ nv50_mstm_del(struct nv50_mstm **pmstm
  {
        struct nv50_mstm *mstm = *pmstm;
        if (mstm) {
+               drm_dp_mst_topology_mgr_destroy(&mstm->mgr);
                kfree(*pmstm);
                *pmstm = NULL;
        }
@@@ -2142,10 -2117,6 +2158,10 @@@ nv50_disp_atomic_check(struct drm_devic
                        return ret;
        }
  
 +      ret = drm_dp_mst_atomic_check(state);
 +      if (ret)
 +              return ret;
 +
        return 0;
  }
  
@@@ -2330,7 -2301,7 +2346,7 @@@ nv50_display_create(struct drm_device *
  
        /* create encoder/connector objects based on VBIOS DCB table */
        for (i = 0, dcbe = &dcb->entry[0]; i < dcb->entries; i++, dcbe++) {
-               connector = nouveau_connector_create(dev, dcbe->connector);
+               connector = nouveau_connector_create(dev, dcbe);
                if (IS_ERR(connector))
                        continue;
  
index 4566e0a75cb8bb660d602d2067d0d5aa207e9a1d,933ebc9f9faaaf35049a53aef49551e3ff1e740a..148b6b20274fc56a08df4176549785e0c84aa67b
@@@ -52,17 -52,44 +52,44 @@@ static const struct drm_encoder_funcs o
        .destroy = omap_encoder_destroy,
  };
  
 -              r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode,
 -                                                           false);
+ static void omap_encoder_hdmi_mode_set(struct drm_encoder *encoder,
+                                      struct drm_display_mode *adjusted_mode)
+ {
+       struct drm_device *dev = encoder->dev;
+       struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+       struct omap_dss_device *dssdev = omap_encoder->output;
+       struct drm_connector *connector;
+       bool hdmi_mode;
+       hdmi_mode = false;
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               if (connector->encoder == encoder) {
+                       hdmi_mode = omap_connector_get_hdmi_mode(connector);
+                       break;
+               }
+       }
+       if (dssdev->ops->hdmi.set_hdmi_mode)
+               dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
+       if (hdmi_mode && dssdev->ops->hdmi.set_infoframe) {
+               struct hdmi_avi_infoframe avi;
+               int r;
++              r = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
++                                                           adjusted_mode);
+               if (r == 0)
+                       dssdev->ops->hdmi.set_infoframe(dssdev, &avi);
+       }
+ }
  static void omap_encoder_mode_set(struct drm_encoder *encoder,
                                  struct drm_display_mode *mode,
                                  struct drm_display_mode *adjusted_mode)
  {
-       struct drm_device *dev = encoder->dev;
        struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-       struct drm_connector *connector;
        struct omap_dss_device *dssdev;
        struct videomode vm = { 0 };
-       bool hdmi_mode;
-       int r;
  
        drm_display_mode_to_videomode(adjusted_mode, &vm);
  
        }
  
        /* Set the HDMI mode and HDMI infoframe if applicable. */
-       hdmi_mode = false;
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               if (connector->encoder == encoder) {
-                       hdmi_mode = omap_connector_get_hdmi_mode(connector);
-                       break;
-               }
-       }
-       dssdev = omap_encoder->output;
-       if (dssdev->ops->hdmi.set_hdmi_mode)
-               dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
-       if (hdmi_mode && dssdev->ops->hdmi.set_infoframe) {
-               struct hdmi_avi_infoframe avi;
-               r = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
-                                                            adjusted_mode);
-               if (r == 0)
-                       dssdev->ops->hdmi.set_infoframe(dssdev, &avi);
-       }
+       if (omap_encoder->output->output_type == OMAP_DISPLAY_TYPE_HDMI)
+               omap_encoder_hdmi_mode_set(encoder, adjusted_mode);
  }
  
  static void omap_encoder_disable(struct drm_encoder *encoder)
index d90bf5f6a67a014957efe8eeb8214bc208c9e025,ef8692b7075ab0f82262b0aae3cb6c57f160d160..44feac2a03594445d180e8f2399288cbf9278f06
@@@ -19,6 -19,8 +19,8 @@@
  
  #include <soc/tegra/pmc.h>
  
+ #include <sound/hda_verbs.h>
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_dp_helper.h>
  #include <drm/drm_panel.h>
  #include "sor.h"
  #include "trace.h"
  
- /*
-  * XXX Remove this after the commit adding it to soc/tegra/pmc.h has been
-  * merged. Having this around after the commit is merged should be safe since
-  * the preprocessor will effectively replace all occurrences and therefore no
-  * duplicate will be defined.
-  */
- #define TEGRA_IO_PAD_HDMI_DP0 26
  #define SOR_REKEY 0x38
  
  struct tegra_sor_hdmi_settings {
@@@ -407,6 -401,7 +401,7 @@@ struct tegra_sor 
        const struct tegra_sor_soc *soc;
        void __iomem *regs;
        unsigned int index;
+       unsigned int irq;
  
        struct reset_control *rst;
        struct clk *clk_parent;
  
        struct delayed_work scdc;
        bool scdc_enabled;
+       struct {
+               unsigned int sample_rate;
+               unsigned int channels;
+       } audio;
  };
  
  struct tegra_sor_state {
@@@ -2116,8 -2116,7 +2116,8 @@@ tegra_sor_hdmi_setup_avi_infoframe(stru
        value &= ~INFOFRAME_CTRL_ENABLE;
        tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
  
 -      err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
 +      err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
 +                                                     &sor->output.connector, mode);
        if (err < 0) {
                dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
                return err;
        return 0;
  }
  
+ static void tegra_sor_write_eld(struct tegra_sor *sor)
+ {
+       size_t length = drm_eld_size(sor->output.connector.eld), i;
+       for (i = 0; i < length; i++)
+               tegra_sor_writel(sor, i << 8 | sor->output.connector.eld[i],
+                                SOR_AUDIO_HDA_ELD_BUFWR);
+       /*
+        * The HDA codec will always report an ELD buffer size of 96 bytes and
+        * the HDA codec driver will check that each byte read from the buffer
+        * is valid. Therefore every byte must be written, even if no 96 bytes
+        * were parsed from EDID.
+        */
+       for (i = length; i < 96; i++)
+               tegra_sor_writel(sor, i << 8 | 0, SOR_AUDIO_HDA_ELD_BUFWR);
+ }
+ static void tegra_sor_audio_prepare(struct tegra_sor *sor)
+ {
+       u32 value;
+       tegra_sor_write_eld(sor);
+       value = SOR_AUDIO_HDA_PRESENSE_ELDV | SOR_AUDIO_HDA_PRESENSE_PD;
+       tegra_sor_writel(sor, value, SOR_AUDIO_HDA_PRESENSE);
+ }
+ static void tegra_sor_audio_unprepare(struct tegra_sor *sor)
+ {
+       tegra_sor_writel(sor, 0, SOR_AUDIO_HDA_PRESENSE);
+ }
+ static int tegra_sor_hdmi_enable_audio_infoframe(struct tegra_sor *sor)
+ {
+       u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)];
+       struct hdmi_audio_infoframe frame;
+       u32 value;
+       int err;
+       err = hdmi_audio_infoframe_init(&frame);
+       if (err < 0) {
+               dev_err(sor->dev, "failed to setup audio infoframe: %d\n", err);
+               return err;
+       }
+       frame.channels = sor->audio.channels;
+       err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
+       if (err < 0) {
+               dev_err(sor->dev, "failed to pack audio infoframe: %d\n", err);
+               return err;
+       }
+       tegra_sor_hdmi_write_infopack(sor, buffer, err);
+       value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
+       value |= INFOFRAME_CTRL_CHECKSUM_ENABLE;
+       value |= INFOFRAME_CTRL_ENABLE;
+       tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
+       return 0;
+ }
+ static void tegra_sor_hdmi_audio_enable(struct tegra_sor *sor)
+ {
+       u32 value;
+       value = tegra_sor_readl(sor, SOR_AUDIO_CNTRL);
+       /* select HDA audio input */
+       value &= ~SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_MASK);
+       value |= SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_HDA);
+       /* inject null samples */
+       if (sor->audio.channels != 2)
+               value &= ~SOR_AUDIO_CNTRL_INJECT_NULLSMPL;
+       else
+               value |= SOR_AUDIO_CNTRL_INJECT_NULLSMPL;
+       value |= SOR_AUDIO_CNTRL_AFIFO_FLUSH;
+       tegra_sor_writel(sor, value, SOR_AUDIO_CNTRL);
+       /* enable advertising HBR capability */
+       tegra_sor_writel(sor, SOR_AUDIO_SPARE_HBR_ENABLE, SOR_AUDIO_SPARE);
+       tegra_sor_writel(sor, 0, SOR_HDMI_ACR_CTRL);
+       value = SOR_HDMI_SPARE_ACR_PRIORITY_HIGH |
+               SOR_HDMI_SPARE_CTS_RESET(1) |
+               SOR_HDMI_SPARE_HW_CTS_ENABLE;
+       tegra_sor_writel(sor, value, SOR_HDMI_SPARE);
+       /* enable HW CTS */
+       value = SOR_HDMI_ACR_SUBPACK_LOW_SB1(0);
+       tegra_sor_writel(sor, value, SOR_HDMI_ACR_0441_SUBPACK_LOW);
+       /* allow packet to be sent */
+       value = SOR_HDMI_ACR_SUBPACK_HIGH_ENABLE;
+       tegra_sor_writel(sor, value, SOR_HDMI_ACR_0441_SUBPACK_HIGH);
+       /* reset N counter and enable lookup */
+       value = SOR_HDMI_AUDIO_N_RESET | SOR_HDMI_AUDIO_N_LOOKUP;
+       tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);
+       value = (24000 * 4096) / (128 * sor->audio.sample_rate / 1000);
+       tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0320);
+       tegra_sor_writel(sor, 4096, SOR_AUDIO_NVAL_0320);
+       tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_0441);
+       tegra_sor_writel(sor, 4704, SOR_AUDIO_NVAL_0441);
+       tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_0882);
+       tegra_sor_writel(sor, 9408, SOR_AUDIO_NVAL_0882);
+       tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_1764);
+       tegra_sor_writel(sor, 18816, SOR_AUDIO_NVAL_1764);
+       value = (24000 * 6144) / (128 * sor->audio.sample_rate / 1000);
+       tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0480);
+       tegra_sor_writel(sor, 6144, SOR_AUDIO_NVAL_0480);
+       value = (24000 * 12288) / (128 * sor->audio.sample_rate / 1000);
+       tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0960);
+       tegra_sor_writel(sor, 12288, SOR_AUDIO_NVAL_0960);
+       value = (24000 * 24576) / (128 * sor->audio.sample_rate / 1000);
+       tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_1920);
+       tegra_sor_writel(sor, 24576, SOR_AUDIO_NVAL_1920);
+       value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_N);
+       value &= ~SOR_HDMI_AUDIO_N_RESET;
+       tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);
+       tegra_sor_hdmi_enable_audio_infoframe(sor);
+ }
  static void tegra_sor_hdmi_disable_audio_infoframe(struct tegra_sor *sor)
  {
        u32 value;
        tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
  }
  
+ static void tegra_sor_hdmi_audio_disable(struct tegra_sor *sor)
+ {
+       tegra_sor_hdmi_disable_audio_infoframe(sor);
+ }
  static struct tegra_sor_hdmi_settings *
  tegra_sor_hdmi_find_settings(struct tegra_sor *sor, unsigned long frequency)
  {
@@@ -2244,6 -2386,7 +2387,7 @@@ static void tegra_sor_hdmi_disable(stru
        u32 value;
        int err;
  
+       tegra_sor_audio_unprepare(sor);
        tegra_sor_hdmi_scdc_stop(sor);
  
        err = tegra_sor_detach(sor);
@@@ -2652,6 -2795,7 +2796,7 @@@ static void tegra_sor_hdmi_enable(struc
                dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);
  
        tegra_sor_hdmi_scdc_start(sor);
+       tegra_sor_audio_prepare(sor);
  }
  
  static const struct drm_encoder_helper_funcs tegra_sor_hdmi_helpers = {
@@@ -2667,6 -2811,7 +2812,7 @@@ static int tegra_sor_init(struct host1x
        struct tegra_sor *sor = host1x_client_to_sor(client);
        int connector = DRM_MODE_CONNECTOR_Unknown;
        int encoder = DRM_MODE_ENCODER_NONE;
+       u32 value;
        int err;
  
        if (!sor->aux) {
        if (err < 0)
                return err;
  
+       /*
+        * Enable and unmask the HDA codec SCRATCH0 register interrupt. This
+        * is used for interoperability between the HDA codec driver and the
+        * HDMI/DP driver.
+        */
+       value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0;
+       tegra_sor_writel(sor, value, SOR_INT_ENABLE);
+       tegra_sor_writel(sor, value, SOR_INT_MASK);
        return 0;
  }
  
@@@ -2768,6 -2922,9 +2923,9 @@@ static int tegra_sor_exit(struct host1x
        struct tegra_sor *sor = host1x_client_to_sor(client);
        int err;
  
+       tegra_sor_writel(sor, 0, SOR_INT_MASK);
+       tegra_sor_writel(sor, 0, SOR_INT_ENABLE);
        tegra_output_exit(&sor->output);
  
        if (sor->aux) {
@@@ -3038,6 -3195,54 +3196,54 @@@ static int tegra_sor_parse_dt(struct te
        return 0;
  }
  
+ static void tegra_hda_parse_format(unsigned int format, unsigned int *rate,
+                                  unsigned int *channels)
+ {
+       unsigned int mul, div;
+       if (format & AC_FMT_BASE_44K)
+               *rate = 44100;
+       else
+               *rate = 48000;
+       mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT;
+       div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT;
+       *rate = *rate * (mul + 1) / (div + 1);
+       *channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT;
+ }
+ static irqreturn_t tegra_sor_irq(int irq, void *data)
+ {
+       struct tegra_sor *sor = data;
+       u32 value;
+       value = tegra_sor_readl(sor, SOR_INT_STATUS);
+       tegra_sor_writel(sor, value, SOR_INT_STATUS);
+       if (value & SOR_INT_CODEC_SCRATCH0) {
+               value = tegra_sor_readl(sor, SOR_AUDIO_HDA_CODEC_SCRATCH0);
+               if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) {
+                       unsigned int format, sample_rate, channels;
+                       format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK;
+                       tegra_hda_parse_format(format, &sample_rate, &channels);
+                       sor->audio.sample_rate = sample_rate;
+                       sor->audio.channels = channels;
+                       tegra_sor_hdmi_audio_enable(sor);
+               } else {
+                       tegra_sor_hdmi_audio_disable(sor);
+               }
+       }
+       return IRQ_HANDLED;
+ }
  static int tegra_sor_probe(struct platform_device *pdev)
  {
        struct device_node *np;
                goto remove;
        }
  
-       if (!pdev->dev.pm_domain) {
-               sor->rst = devm_reset_control_get(&pdev->dev, "sor");
-               if (IS_ERR(sor->rst)) {
-                       err = PTR_ERR(sor->rst);
+       err = platform_get_irq(pdev, 0);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);
+               goto remove;
+       }
+       sor->irq = err;
+       err = devm_request_irq(sor->dev, sor->irq, tegra_sor_irq, 0,
+                              dev_name(sor->dev), sor);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
+               goto remove;
+       }
+       sor->rst = devm_reset_control_get(&pdev->dev, "sor");
+       if (IS_ERR(sor->rst)) {
+               err = PTR_ERR(sor->rst);
+               if (err != -EBUSY || WARN_ON(!pdev->dev.pm_domain)) {
                        dev_err(&pdev->dev, "failed to get reset control: %d\n",
                                err);
                        goto remove;
                }
+               /*
+                * At this point, the reset control is most likely being used
+                * by the generic power domain implementation. With any luck
+                * the power domain will have taken care of resetting the SOR
+                * and we don't have to do anything.
+                */
+               sor->rst = NULL;
        }
  
        sor->clk = devm_clk_get(&pdev->dev, NULL);
index e8ad30d7561afe7948bebcd8215a0ae03576b04b,f82701d49ea680556ea4f00fedcf570928e295ef..994161374a4928e33e668674f8120589d6661bc1
@@@ -365,12 -365,6 +365,12 @@@ struct drm_display_info 
         */
        bool has_hdmi_infoframe;
  
 +      /**
 +       * @rgb_quant_range_selectable: Does the sink support selecting
 +       * the RGB quantization range?
 +       */
 +      bool rgb_quant_range_selectable;
 +
        /**
         * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even
         * more stuff redundant with @bus_formats.
@@@ -977,6 -971,17 +977,17 @@@ struct drm_connector 
         */
        struct drm_property *scaling_mode_property;
  
+       /**
+        * @vrr_capable_property: Optional property to help userspace
+        * query hardware support for variable refresh rate on a connector.
+        * connector. Drivers can add the property to a connector by
+        * calling drm_connector_attach_vrr_capable_property().
+        *
+        * This should be updated only by calling
+        * drm_connector_set_vrr_capable_property().
+        */
+       struct drm_property *vrr_capable_property;
        /**
         * @content_protection_property: DRM ENUM property for content
         * protection. See drm_connector_attach_content_protection_property().
@@@ -1253,6 -1258,8 +1264,8 @@@ int drm_mode_create_scaling_mode_proper
  int drm_connector_attach_content_type_property(struct drm_connector *dev);
  int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
                                               u32 scaling_mode_mask);
+ int drm_connector_attach_vrr_capable_property(
+               struct drm_connector *connector);
  int drm_connector_attach_content_protection_property(
                struct drm_connector *connector);
  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
@@@ -1269,6 -1276,8 +1282,8 @@@ int drm_connector_update_edid_property(
                                       const struct edid *edid);
  void drm_connector_set_link_status_property(struct drm_connector *connector,
                                            uint64_t link_status);
+ void drm_connector_set_vrr_capable_property(
+               struct drm_connector *connector, bool capable);
  int drm_connector_init_panel_orientation_property(
        struct drm_connector *connector, int width, int height);
  int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
diff --combined include/drm/drm_crtc.h
index b955ef1f1e3e5dd4d46777395f583db1b1bd4482,39c3900aab3cea107a0771b6fe0d5dc510ac4c11..b45bec0b7a9c557e139769b08828c02a2736e74f
@@@ -290,6 -290,15 +290,15 @@@ struct drm_crtc_state 
         */
        u32 pageflip_flags;
  
+       /**
+        * @vrr_enabled:
+        *
+        * Indicates if variable refresh rate should be enabled for the CRTC.
+        * Support for the requested vrr state will depend on driver and
+        * hardware capabiltiy - lacking support is not treated as failure.
+        */
+       bool vrr_enabled;
        /**
         * @event:
         *
@@@ -1140,6 -1149,7 +1149,6 @@@ static inline uint32_t drm_crtc_mask(co
        return 1 << drm_crtc_index(crtc);
  }
  
 -int drm_crtc_force_disable(struct drm_crtc *crtc);
  int drm_crtc_force_disable_all(struct drm_device *dev);
  
  int drm_mode_set_config_internal(struct drm_mode_set *set);