Merge tag 'drm-intel-next-2023-12-07' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Fri, 8 Dec 2023 05:06:04 +0000 (15:06 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 8 Dec 2023 05:06:14 +0000 (15:06 +1000)
- Improve display debug msgs and other general clean-ups (Ville, Rahuul)
- PSR fixes and improvements around selective fetch (Jouni, Ville)
- Remove FBC restrictions for Xe2LPD displays (Vinod)
- Skip some timing checks on BXT/GLK DSI transcoders (Ville)
- DP MST Fixes (Ville)
- Correct the input parameter on _intel_dsb_commit (heminhong)
- Fix IP version of the display WAs (Bala)
- DGFX uses direct VBT pin mapping (Clint)
- Proper handling of bool on PIPE_CONF_CHECK macros (Jani)
- Skip state verification with TBT-ALT mod (Mika Kahona)
- General organization of display code for reusage with Xe
  (Jouni, Luca, Jani, Maarten)
- Squelch a sparse warning (Jani)
- Don't use "proxy" headers (Andy Shevchenko)
- Use devm_gpiod_get() for all GPIOs (Hans)
- Fix ADL+ tiled plane stride (Ville)
- Use octal permissions in display debugfs (Jani)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ZXIWG6bRYaUw0w6-@intel.com
1  2 
drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
drivers/gpu/drm/i915/display/intel_display_debugfs.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_fb.c
drivers/gpu/drm/i915/display/intel_sdvo.c

index 2d15e82c0b3d3dcdd7ad95f20526bf52931335be,30b8ddeae8cef0d8cde9ec95016c525ef3b6aaad..49fd100ec98a021012cab38c8adda4e6efb5804b
@@@ -4,7 -4,6 +4,7 @@@
   */
  
  #include <drm/drm_edid.h>
 +#include <drm/drm_eld.h>
  
  #include "i915_drv.h"
  #include "intel_crtc_state_dump.h"
@@@ -262,6 -261,15 +262,15 @@@ void intel_crtc_state_dump(const struc
                drm_dbg_kms(&i915->drm, "fec: %s, enhanced framing: %s\n",
                            str_enabled_disabled(pipe_config->fec_enable),
                            str_enabled_disabled(pipe_config->enhanced_framing));
+               drm_dbg_kms(&i915->drm, "sdp split: %s\n",
+                           str_enabled_disabled(pipe_config->sdp_split_enable));
+               drm_dbg_kms(&i915->drm, "psr: %s, psr2: %s, panel replay: %s, selective fetch: %s\n",
+                           str_enabled_disabled(pipe_config->has_psr),
+                           str_enabled_disabled(pipe_config->has_psr2),
+                           str_enabled_disabled(pipe_config->has_panel_replay),
+                           str_enabled_disabled(pipe_config->enable_psr2_sel_fetch));
        }
  
        drm_dbg_kms(&i915->drm, "framestart delay: %d, MSA timing delay: %d\n",
index 915420d0cef8f9ac402e2aa361a58dcdaa6153dc,0cb819fc2a0cf23079ef0eb937de5ce1a582f7ed..d951edb3668714480b56eae2314c2a91b00e7301
@@@ -238,13 -238,14 +238,13 @@@ static void intel_dp_info(struct seq_fi
  {
        struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
        struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
 -      const struct edid *edid = drm_edid_raw(connector->detect_edid);
  
        seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
        seq_printf(m, "\taudio support: %s\n",
                   str_yes_no(connector->base.display_info.has_audio));
  
        drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
 -                              edid, &intel_dp->aux);
 +                              connector->detect_edid, &intel_dp->aux);
  }
  
  static void intel_dp_mst_info(struct seq_file *m,
@@@ -1095,7 -1096,7 +1095,7 @@@ void intel_display_debugfs_register(str
  
        for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) {
                debugfs_create_file(intel_display_debugfs_files[i].name,
-                                   S_IRUGO | S_IWUSR,
+                                   0644,
                                    minor->debugfs_root,
                                    to_i915(minor->dev),
                                    intel_display_debugfs_files[i].fops);
  
  static int i915_panel_show(struct seq_file *m, void *data)
  {
-       struct drm_connector *connector = m->private;
-       struct intel_dp *intel_dp =
-               intel_attached_dp(to_intel_connector(connector));
+       struct intel_connector *connector = m->private;
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
  
-       if (connector->status != connector_status_connected)
+       if (connector->base.status != connector_status_connected)
                return -ENODEV;
  
        seq_printf(m, "Panel power up delay: %d\n",
@@@ -1138,23 -1138,23 +1137,23 @@@ DEFINE_SHOW_ATTRIBUTE(i915_panel)
  
  static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
  {
-       struct drm_connector *connector = m->private;
-       struct drm_i915_private *i915 = to_i915(connector->dev);
-       struct intel_connector *intel_connector = to_intel_connector(connector);
+       struct intel_connector *connector = m->private;
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
        int ret;
  
        ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
        if (ret)
                return ret;
  
-       if (!connector->encoder || connector->status != connector_status_connected) {
+       if (!connector->base.encoder ||
+           connector->base.status != connector_status_connected) {
                ret = -ENODEV;
                goto out;
        }
  
-       seq_printf(m, "%s:%d HDCP version: ", connector->name,
-                  connector->base.id);
-       intel_hdcp_info(m, intel_connector);
+       seq_printf(m, "%s:%d HDCP version: ", connector->base.name,
+                  connector->base.base.id);
+       intel_hdcp_info(m, connector);
  
  out:
        drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
@@@ -1165,16 -1165,16 +1164,16 @@@ DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_ca
  
  static int i915_lpsp_capability_show(struct seq_file *m, void *data)
  {
-       struct drm_connector *connector = m->private;
-       struct drm_i915_private *i915 = to_i915(connector->dev);
-       struct intel_encoder *encoder;
+       struct intel_connector *connector = m->private;
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
+       int connector_type = connector->base.connector_type;
        bool lpsp_capable = false;
  
-       encoder = intel_attached_encoder(to_intel_connector(connector));
        if (!encoder)
                return -ENODEV;
  
-       if (connector->status != connector_status_connected)
+       if (connector->base.status != connector_status_connected)
                return -ENODEV;
  
        if (DISPLAY_VER(i915) >= 13)
                 */
                lpsp_capable = encoder->port <= PORT_B;
        else if (DISPLAY_VER(i915) == 11)
-               lpsp_capable = (connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
-                               connector->connector_type == DRM_MODE_CONNECTOR_eDP);
+               lpsp_capable = (connector_type == DRM_MODE_CONNECTOR_DSI ||
+                               connector_type == DRM_MODE_CONNECTOR_eDP);
        else if (IS_DISPLAY_VER(i915, 9, 10))
                lpsp_capable = (encoder->port == PORT_A &&
-                               (connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
-                                connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
-                                connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort));
+                               (connector_type == DRM_MODE_CONNECTOR_DSI ||
+                                connector_type == DRM_MODE_CONNECTOR_eDP ||
+                                connector_type == DRM_MODE_CONNECTOR_DisplayPort));
        else if (IS_HASWELL(i915) || IS_BROADWELL(i915))
-               lpsp_capable = connector->connector_type == DRM_MODE_CONNECTOR_eDP;
+               lpsp_capable = connector_type == DRM_MODE_CONNECTOR_eDP;
  
        seq_printf(m, "LPSP: %s\n", lpsp_capable ? "capable" : "incapable");
  
@@@ -1205,7 -1205,7 +1204,7 @@@ DEFINE_SHOW_ATTRIBUTE(i915_lpsp_capabil
  
  static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
  {
-       struct intel_connector *connector = to_intel_connector(m->private);
+       struct intel_connector *connector = m->private;
        struct drm_i915_private *i915 = to_i915(connector->base.dev);
        struct drm_crtc *crtc;
        struct intel_dp *intel_dp;
@@@ -1275,13 -1275,13 +1274,13 @@@ static ssize_t i915_dsc_fec_support_wri
                                          const char __user *ubuf,
                                          size_t len, loff_t *offp)
  {
+       struct seq_file *m = file->private_data;
+       struct intel_connector *connector = m->private;
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
+       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        bool dsc_enable = false;
        int ret;
-       struct drm_connector *connector =
-               ((struct seq_file *)file->private_data)->private;
-       struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
-       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
  
        if (len == 0)
                return 0;
@@@ -1319,22 -1319,22 +1318,22 @@@ static const struct file_operations i91
  
  static int i915_dsc_bpc_show(struct seq_file *m, void *data)
  {
-       struct drm_connector *connector = m->private;
-       struct drm_device *dev = connector->dev;
+       struct intel_connector *connector = m->private;
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
        struct drm_crtc *crtc;
        struct intel_crtc_state *crtc_state;
-       struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
        int ret;
  
        if (!encoder)
                return -ENODEV;
  
-       ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex);
+       ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
        if (ret)
                return ret;
  
-       crtc = connector->state->crtc;
-       if (connector->status != connector_status_connected || !crtc) {
+       crtc = connector->base.state->crtc;
+       if (connector->base.status != connector_status_connected || !crtc) {
                ret = -ENODEV;
                goto out;
        }
        crtc_state = to_intel_crtc_state(crtc->state);
        seq_printf(m, "Input_BPC: %d\n", crtc_state->dsc.config.bits_per_component);
  
- out:  drm_modeset_unlock(&dev->mode_config.connection_mutex);
+ out:  drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
  
        return ret;
  }
@@@ -1351,9 -1351,9 +1350,9 @@@ static ssize_t i915_dsc_bpc_write(struc
                                  const char __user *ubuf,
                                  size_t len, loff_t *offp)
  {
-       struct drm_connector *connector =
-               ((struct seq_file *)file->private_data)->private;
-       struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
+       struct seq_file *m = file->private_data;
+       struct intel_connector *connector = m->private;
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        int dsc_bpc = 0;
        int ret;
@@@ -1385,22 -1385,22 +1384,22 @@@ static const struct file_operations i91
  
  static int i915_dsc_output_format_show(struct seq_file *m, void *data)
  {
-       struct drm_connector *connector = m->private;
-       struct drm_device *dev = connector->dev;
+       struct intel_connector *connector = m->private;
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
        struct drm_crtc *crtc;
        struct intel_crtc_state *crtc_state;
-       struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
        int ret;
  
        if (!encoder)
                return -ENODEV;
  
-       ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex);
+       ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
        if (ret)
                return ret;
  
-       crtc = connector->state->crtc;
-       if (connector->status != connector_status_connected || !crtc) {
+       crtc = connector->base.state->crtc;
+       if (connector->base.status != connector_status_connected || !crtc) {
                ret = -ENODEV;
                goto out;
        }
        seq_printf(m, "DSC_Output_Format: %s\n",
                   intel_output_format_name(crtc_state->output_format));
  
- out:  drm_modeset_unlock(&dev->mode_config.connection_mutex);
+ out:  drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
  
        return ret;
  }
@@@ -1418,9 -1418,9 +1417,9 @@@ static ssize_t i915_dsc_output_format_w
                                            const char __user *ubuf,
                                            size_t len, loff_t *offp)
  {
-       struct drm_connector *connector =
-               ((struct seq_file *)file->private_data)->private;
-       struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
+       struct seq_file *m = file->private_data;
+       struct intel_connector *connector = m->private;
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        int dsc_output_format = 0;
        int ret;
@@@ -1452,33 -1452,32 +1451,32 @@@ static const struct file_operations i91
  
  static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data)
  {
-       struct drm_connector *connector = m->private;
-       struct drm_device *dev = connector->dev;
+       struct intel_connector *connector = m->private;
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
        struct drm_crtc *crtc;
        struct intel_dp *intel_dp;
-       struct intel_connector *intel_connector = to_intel_connector(connector);
-       struct intel_encoder *encoder = intel_attached_encoder(intel_connector);
        int ret;
  
        if (!encoder)
                return -ENODEV;
  
-       ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex);
+       ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
        if (ret)
                return ret;
  
-       crtc = connector->state->crtc;
-       if (connector->status != connector_status_connected || !crtc) {
+       crtc = connector->base.state->crtc;
+       if (connector->base.status != connector_status_connected || !crtc) {
                ret = -ENODEV;
                goto out;
        }
  
-       intel_dp = intel_attached_dp(intel_connector);
+       intel_dp = intel_attached_dp(connector);
        seq_printf(m, "Force_DSC_Fractional_BPP_Enable: %s\n",
                   str_yes_no(intel_dp->force_dsc_fractional_bpp_en));
  
  out:
-       drm_modeset_unlock(&dev->mode_config.connection_mutex);
+       drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
  
        return ret;
  }
@@@ -1487,10 -1486,10 +1485,10 @@@ static ssize_t i915_dsc_fractional_bpp_
                                             const char __user *ubuf,
                                             size_t len, loff_t *offp)
  {
-       struct drm_connector *connector =
-               ((struct seq_file *)file->private_data)->private;
-       struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
-       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct seq_file *m = file->private_data;
+       struct intel_connector *connector = m->private;
+       struct intel_encoder *encoder = intel_attached_encoder(connector);
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        bool dsc_fractional_bpp_enable = false;
        int ret;
@@@ -1565,39 -1564,38 +1563,38 @@@ DEFINE_SHOW_ATTRIBUTE(intel_crtc_pipe)
  
  /**
   * intel_connector_debugfs_add - add i915 specific connector debugfs files
-  * @intel_connector: pointer to a registered drm_connector
+  * @connector: pointer to a registered intel_connector
   *
   * Cleanup will be done by drm_connector_unregister() through a call to
   * drm_debugfs_connector_remove().
   */
- void intel_connector_debugfs_add(struct intel_connector *intel_connector)
+ void intel_connector_debugfs_add(struct intel_connector *connector)
  {
-       struct drm_connector *connector = &intel_connector->base;
-       struct dentry *root = connector->debugfs_entry;
-       struct drm_i915_private *dev_priv = to_i915(connector->dev);
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct dentry *root = connector->base.debugfs_entry;
+       int connector_type = connector->base.connector_type;
  
        /* The connector must have been registered beforehands. */
        if (!root)
                return;
  
-       intel_drrs_connector_debugfs_add(intel_connector);
-       intel_psr_connector_debugfs_add(intel_connector);
+       intel_drrs_connector_debugfs_add(connector);
+       intel_psr_connector_debugfs_add(connector);
  
-       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
-               debugfs_create_file("i915_panel_timings", S_IRUGO, root,
+       if (connector_type == DRM_MODE_CONNECTOR_eDP)
+               debugfs_create_file("i915_panel_timings", 0444, root,
                                    connector, &i915_panel_fops);
  
-       if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
-           connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
-           connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
-               debugfs_create_file("i915_hdcp_sink_capability", S_IRUGO, root,
+       if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+           connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+           connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+               debugfs_create_file("i915_hdcp_sink_capability", 0444, root,
                                    connector, &i915_hdcp_sink_capability_fops);
        }
  
-       if (DISPLAY_VER(dev_priv) >= 11 &&
-           ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
-           !to_intel_connector(connector)->mst_port) ||
-           connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+       if (DISPLAY_VER(i915) >= 11 &&
+           ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) ||
+            connector_type == DRM_MODE_CONNECTOR_eDP)) {
                debugfs_create_file("i915_dsc_fec_support", 0644, root,
                                    connector, &i915_dsc_fec_support_fops);
  
                                    connector, &i915_dsc_fractional_bpp_fops);
        }
  
-       if (connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
-           connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
-           connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
-           connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
-           connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
+       if (connector_type == DRM_MODE_CONNECTOR_DSI ||
+           connector_type == DRM_MODE_CONNECTOR_eDP ||
+           connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+           connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+           connector_type == DRM_MODE_CONNECTOR_HDMIB)
                debugfs_create_file("i915_lpsp_capability", 0444, root,
                                    connector, &i915_lpsp_capability_fops);
  }
index 1422c23702698a3e5d0e1a6546543e6668ee21a6,0b24c0cba94e31f4d5e5a58678897d37d60f726b..3b2482bf683ff3c9b7dd5caa3c9a83db7ac476fe
@@@ -1227,6 -1227,10 +1227,10 @@@ intel_dp_mode_valid(struct drm_connecto
        enum drm_mode_status status;
        bool dsc = false, bigjoiner = false;
  
+       status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
+       if (status != MODE_OK)
+               return status;
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                return MODE_H_ILLEGAL;
  
@@@ -1886,7 -1890,7 +1890,7 @@@ static int dsc_src_max_compressed_bpp(s
         * Max Compressed bpp for Gen 13+ is 27bpp.
         * For earlier platform is 23bpp. (Bspec:49259).
         */
-       if (DISPLAY_VER(i915) <= 12)
+       if (DISPLAY_VER(i915) < 13)
                return 23;
        else
                return 27;
@@@ -2844,19 -2848,12 +2848,12 @@@ intel_dp_audio_compute_config(struct in
                              struct intel_crtc_state *pipe_config,
                              struct drm_connector_state *conn_state)
  {
-       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-       struct drm_connector *connector = conn_state->connector;
        pipe_config->has_audio =
                intel_dp_has_audio(encoder, pipe_config, conn_state) &&
                intel_audio_compute_config(encoder, pipe_config, conn_state);
  
        pipe_config->sdp_split_enable = pipe_config->has_audio &&
                                        intel_dp_is_uhbr(pipe_config);
-       drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n",
-                   connector->base.id, connector->name,
-                   str_yes_no(pipe_config->sdp_split_enable));
  }
  
  int
@@@ -5504,10 -5501,14 +5501,10 @@@ intel_dp_update_dfp(struct intel_dp *in
  {
        struct drm_i915_private *i915 = dp_to_i915(intel_dp);
        struct intel_connector *connector = intel_dp->attached_connector;
 -      const struct edid *edid;
 -
 -      /* FIXME: Get rid of drm_edid_raw() */
 -      edid = drm_edid_raw(drm_edid);
  
        intel_dp->dfp.max_bpc =
                drm_dp_downstream_max_bpc(intel_dp->dpcd,
 -                                        intel_dp->downstream_ports, edid);
 +                                        intel_dp->downstream_ports, drm_edid);
  
        intel_dp->dfp.max_dotclock =
                drm_dp_downstream_max_dotclock(intel_dp->dpcd,
        intel_dp->dfp.min_tmds_clock =
                drm_dp_downstream_min_tmds_clock(intel_dp->dpcd,
                                                 intel_dp->downstream_ports,
 -                                               edid);
 +                                               drm_edid);
        intel_dp->dfp.max_tmds_clock =
                drm_dp_downstream_max_tmds_clock(intel_dp->dpcd,
                                                 intel_dp->downstream_ports,
 -                                               edid);
 +                                               drm_edid);
  
        intel_dp->dfp.pcon_max_frl_bw =
                drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd,
@@@ -6038,26 -6039,15 +6035,26 @@@ static int intel_dp_connector_atomic_ch
        return intel_modeset_synced_crtcs(state, conn);
  }
  
 -static void intel_dp_oob_hotplug_event(struct drm_connector *connector)
 +static void intel_dp_oob_hotplug_event(struct drm_connector *connector,
 +                                     enum drm_connector_status hpd_state)
  {
        struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
        struct drm_i915_private *i915 = to_i915(connector->dev);
 +      bool hpd_high = hpd_state == connector_status_connected;
 +      unsigned int hpd_pin = encoder->hpd_pin;
 +      bool need_work = false;
  
        spin_lock_irq(&i915->irq_lock);
 -      i915->display.hotplug.event_bits |= BIT(encoder->hpd_pin);
 +      if (hpd_high != test_bit(hpd_pin, &i915->display.hotplug.oob_hotplug_last_state)) {
 +              i915->display.hotplug.event_bits |= BIT(hpd_pin);
 +
 +              __assign_bit(hpd_pin, &i915->display.hotplug.oob_hotplug_last_state, hpd_high);
 +              need_work = true;
 +      }
        spin_unlock_irq(&i915->irq_lock);
 -      queue_delayed_work(i915->unordered_wq, &i915->display.hotplug.hotplug_work, 0);
 +
 +      if (need_work)
 +              queue_delayed_work(i915->unordered_wq, &i915->display.hotplug.hotplug_work, 0);
  }
  
  static const struct drm_connector_funcs intel_dp_connector_funcs = {
index 6d48aa3af95a314c4f431c427084006994da9c49,4f9d2e57a770ac3a5bba466139e682e544f3d0d8..69c3cfe3120e7142e3cf1e14f1c6f23a3058c6c1
@@@ -4,7 -4,6 +4,6 @@@
   */
  
  #include <drm/drm_blend.h>
- #include <drm/drm_framebuffer.h>
  #include <drm/drm_modeset_helper.h>
  
  #include <linux/dma-fence.h>
@@@ -15,6 -14,7 +14,7 @@@
  #include "intel_display_types.h"
  #include "intel_dpt.h"
  #include "intel_fb.h"
+ #include "intel_fb_bo.h"
  #include "intel_frontbuffer.h"
  
  #define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a))
@@@ -301,6 -301,33 +301,33 @@@ lookup_format_info(const struct drm_for
        return NULL;
  }
  
+ unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
+ {
+       const struct intel_modifier_desc *md;
+       u8 tiling_caps;
+       md = lookup_modifier_or_null(fb_modifier);
+       if (!md)
+               return I915_TILING_NONE;
+       tiling_caps = lookup_modifier_or_null(fb_modifier)->plane_caps &
+                        INTEL_PLANE_CAP_TILING_MASK;
+       switch (tiling_caps) {
+       case INTEL_PLANE_CAP_TILING_Y:
+               return I915_TILING_Y;
+       case INTEL_PLANE_CAP_TILING_X:
+               return I915_TILING_X;
+       case INTEL_PLANE_CAP_TILING_4:
+       case INTEL_PLANE_CAP_TILING_Yf:
+       case INTEL_PLANE_CAP_TILING_NONE:
+               return I915_TILING_NONE;
+       default:
+               MISSING_CASE(tiling_caps);
+               return I915_TILING_NONE;
+       }
+ }
  /**
   * intel_fb_get_format_info: Get a modifier specific format information
   * @cmd: FB add command structure
@@@ -737,26 -764,6 +764,6 @@@ intel_fb_align_height(const struct drm_
        return ALIGN(height, tile_height);
  }
  
- static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
- {
-       u8 tiling_caps = lookup_modifier(fb_modifier)->plane_caps &
-                        INTEL_PLANE_CAP_TILING_MASK;
-       switch (tiling_caps) {
-       case INTEL_PLANE_CAP_TILING_Y:
-               return I915_TILING_Y;
-       case INTEL_PLANE_CAP_TILING_X:
-               return I915_TILING_X;
-       case INTEL_PLANE_CAP_TILING_4:
-       case INTEL_PLANE_CAP_TILING_Yf:
-       case INTEL_PLANE_CAP_TILING_NONE:
-               return I915_TILING_NONE;
-       default:
-               MISSING_CASE(tiling_caps);
-               return I915_TILING_NONE;
-       }
- }
  bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier)
  {
        return HAS_DPT(i915) && modifier != DRM_FORMAT_MOD_LINEAR;
@@@ -1117,7 -1124,7 +1124,7 @@@ static int intel_fb_offset_to_xy(int *x
                return -EINVAL;
        }
  
 -      height = drm_framebuffer_plane_height(fb->height, fb, color_plane);
 +      height = drm_format_info_plane_height(fb->format, fb->height, color_plane);
        height = ALIGN(height, intel_tile_height(fb, color_plane));
  
        /* Catch potential overflows early */
@@@ -1374,7 -1381,8 +1381,8 @@@ plane_view_scanout_stride(const struct 
        struct drm_i915_private *i915 = to_i915(fb->base.dev);
        unsigned int stride_tiles;
  
-       if (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)
+       if ((IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) &&
+           src_stride_tiles < dst_stride_tiles)
                stride_tiles = src_stride_tiles;
        else
                stride_tiles = dst_stride_tiles;
@@@ -1657,10 -1665,10 +1665,10 @@@ int intel_fill_fb_info(struct drm_i915_
                max_size = max(max_size, offset + size);
        }
  
-       if (mul_u32_u32(max_size, tile_size) > obj->base.size) {
+       if (mul_u32_u32(max_size, tile_size) > intel_bo_to_drm_bo(obj)->size) {
                drm_dbg_kms(&i915->drm,
                            "fb too big for bo (need %llu bytes, have %zu bytes)\n",
-                           mul_u32_u32(max_size, tile_size), obj->base.size);
+                           mul_u32_u32(max_size, tile_size), intel_bo_to_drm_bo(obj)->size);
                return -EINVAL;
        }
  
@@@ -1881,6 -1889,8 +1889,8 @@@ static void intel_user_framebuffer_dest
  
        intel_frontbuffer_put(intel_fb->frontbuffer);
  
+       intel_fb_bo_framebuffer_fini(intel_fb_obj(fb));
        kfree(intel_fb);
  }
  
@@@ -1889,7 -1899,7 +1899,7 @@@ static int intel_user_framebuffer_creat
                                                unsigned int *handle)
  {
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-       struct drm_i915_private *i915 = to_i915(obj->base.dev);
+       struct drm_i915_private *i915 = to_i915(intel_bo_to_drm_bo(obj)->dev);
  
        if (i915_gem_object_is_userptr(obj)) {
                drm_dbg(&i915->drm,
                return -EINVAL;
        }
  
-       return drm_gem_handle_create(file, &obj->base, handle);
+       return drm_gem_handle_create(file, intel_bo_to_drm_bo(obj), handle);
  }
  
  struct frontbuffer_fence_cb {
@@@ -1975,61 -1985,30 +1985,30 @@@ int intel_framebuffer_init(struct intel
                           struct drm_i915_gem_object *obj,
                           struct drm_mode_fb_cmd2 *mode_cmd)
  {
-       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+       struct drm_i915_private *dev_priv = to_i915(intel_bo_to_drm_bo(obj)->dev);
        struct drm_framebuffer *fb = &intel_fb->base;
        u32 max_stride;
-       unsigned int tiling, stride;
        int ret = -EINVAL;
        int i;
  
-       intel_fb->frontbuffer = intel_frontbuffer_get(obj);
-       if (!intel_fb->frontbuffer)
-               return -ENOMEM;
-       i915_gem_object_lock(obj, NULL);
-       tiling = i915_gem_object_get_tiling(obj);
-       stride = i915_gem_object_get_stride(obj);
-       i915_gem_object_unlock(obj);
+       ret = intel_fb_bo_framebuffer_init(intel_fb, obj, mode_cmd);
+       if (ret)
+               return ret;
  
-       if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
-               /*
-                * If there's a fence, enforce that
-                * the fb modifier and tiling mode match.
-                */
-               if (tiling != I915_TILING_NONE &&
-                   tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "tiling_mode doesn't match fb modifier\n");
-                       goto err;
-               }
-       } else {
-               if (tiling == I915_TILING_X) {
-                       mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
-               } else if (tiling == I915_TILING_Y) {
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "No Y tiling for legacy addfb\n");
-                       goto err;
-               }
+       intel_fb->frontbuffer = intel_frontbuffer_get(obj);
+       if (!intel_fb->frontbuffer) {
+               ret = -ENOMEM;
+               goto err;
        }
  
+       ret = -EINVAL;
        if (!drm_any_plane_has_format(&dev_priv->drm,
                                      mode_cmd->pixel_format,
                                      mode_cmd->modifier[0])) {
                drm_dbg_kms(&dev_priv->drm,
                            "unsupported pixel format %p4cc / modifier 0x%llx\n",
                            &mode_cmd->pixel_format, mode_cmd->modifier[0]);
-               goto err;
-       }
-       /*
-        * gen2/3 display engine uses the fence if present,
-        * so the tiling mode must match the fb modifier exactly.
-        */
-       if (DISPLAY_VER(dev_priv) < 4 &&
-           tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
-               drm_dbg_kms(&dev_priv->drm,
-                           "tiling_mode must match fb modifier exactly on gen2/3\n");
-               goto err;
+               goto err_frontbuffer_put;
        }
  
        max_stride = intel_fb_max_stride(dev_priv, mode_cmd->pixel_format,
                            mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ?
                            "tiled" : "linear",
                            mode_cmd->pitches[0], max_stride);
-               goto err;
-       }
-       /*
-        * If there's a fence, enforce that
-        * the fb pitch and fence stride match.
-        */
-       if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) {
-               drm_dbg_kms(&dev_priv->drm,
-                           "pitch (%d) must match tiling stride (%d)\n",
-                           mode_cmd->pitches[0], stride);
-               goto err;
+               goto err_frontbuffer_put;
        }
  
        /* FIXME need to adjust LINOFF/TILEOFF accordingly. */
                drm_dbg_kms(&dev_priv->drm,
                            "plane 0 offset (0x%08x) must be 0\n",
                            mode_cmd->offsets[0]);
-               goto err;
+               goto err_frontbuffer_put;
        }
  
        drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
                if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
                        drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n",
                                    i);
-                       goto err;
+                       goto err_frontbuffer_put;
                }
  
                stride_alignment = intel_fb_stride_alignment(fb, i);
                        drm_dbg_kms(&dev_priv->drm,
                                    "plane %d pitch (%d) must be at least %u byte aligned\n",
                                    i, fb->pitches[i], stride_alignment);
-                       goto err;
+                       goto err_frontbuffer_put;
                }
  
                if (intel_fb_is_gen12_ccs_aux_plane(fb, i)) {
                                            "ccs aux plane %d pitch (%d) must be %d\n",
                                            i,
                                            fb->pitches[i], ccs_aux_stride);
-                               goto err;
+                               goto err_frontbuffer_put;
                        }
                }
  
  
        ret = intel_fill_fb_info(dev_priv, intel_fb);
        if (ret)
-               goto err;
+               goto err_frontbuffer_put;
  
        if (intel_fb_uses_dpt(fb)) {
                struct i915_address_space *vm;
                if (IS_ERR(vm)) {
                        drm_dbg_kms(&dev_priv->drm, "failed to create DPT\n");
                        ret = PTR_ERR(vm);
-                       goto err;
+                       goto err_frontbuffer_put;
                }
  
                intel_fb->dpt_vm = vm;
  err_free_dpt:
        if (intel_fb_uses_dpt(fb))
                intel_dpt_destroy(intel_fb->dpt_vm);
- err:
+ err_frontbuffer_put:
        intel_frontbuffer_put(intel_fb->frontbuffer);
+ err:
+       intel_fb_bo_framebuffer_fini(obj);
        return ret;
  }
  
@@@ -2137,23 -2107,14 +2107,14 @@@ intel_user_framebuffer_create(struct dr
        struct drm_framebuffer *fb;
        struct drm_i915_gem_object *obj;
        struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
-       struct drm_i915_private *i915;
-       obj = i915_gem_object_lookup(filp, mode_cmd.handles[0]);
-       if (!obj)
-               return ERR_PTR(-ENOENT);
-       /* object is backed with LMEM for discrete */
-       i915 = to_i915(obj->base.dev);
-       if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM_0)) {
-               /* object is "remote", not in local memory */
-               i915_gem_object_put(obj);
-               drm_dbg_kms(&i915->drm, "framebuffer must reside in local memory\n");
-               return ERR_PTR(-EREMOTE);
-       }
+       struct drm_i915_private *i915 = to_i915(dev);
+       obj = intel_fb_bo_lookup_valid_bo(i915, filp, &mode_cmd);
+       if (IS_ERR(obj))
+               return ERR_CAST(obj);
  
        fb = intel_framebuffer_create(obj, &mode_cmd);
-       i915_gem_object_put(obj);
+       drm_gem_object_put(intel_bo_to_drm_bo(obj));
  
        return fb;
  }
index bcb4959df70d13479792624b336e941bfade17fd,0362d02d70b6a5e06874642d4261197ac16c34f0..9218047495fb41980778f8850805e2178677d50e
@@@ -35,7 -35,6 +35,7 @@@
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_crtc.h>
  #include <drm/drm_edid.h>
 +#include <drm/drm_eld.h>
  
  #include "i915_drv.h"
  #include "i915_reg.h"
@@@ -1931,13 -1930,19 +1931,19 @@@ static enum drm_mode_statu
  intel_sdvo_mode_valid(struct drm_connector *connector,
                      struct drm_display_mode *mode)
  {
+       struct drm_i915_private *i915 = to_i915(connector->dev);
        struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));
        struct intel_sdvo_connector *intel_sdvo_connector =
                to_intel_sdvo_connector(connector);
-       int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
        bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state);
+       int max_dotclk = i915->max_dotclk_freq;
+       enum drm_mode_status status;
        int clock = mode->clock;
  
+       status = intel_cpu_transcoder_mode_valid(i915, mode);
+       if (status != MODE_OK)
+               return status;
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;