intel_dp->aux.i2c_defer_count);
                intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
        } else {
-               struct edid *block = intel_connector->detect_edid;
+               /* FIXME: Get rid of drm_edid_raw() */
+               const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
 
-               /* We have to write the checksum
-                * of the last block read
-                */
-               block += intel_connector->detect_edid->extensions;
+               /* We have to write the checksum of the last block read */
+               block += block->extensions;
 
                if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
                                       block->checksum) <= 0)
        return is_connected;
 }
 
-static struct edid *
+static const struct drm_edid *
 intel_dp_get_edid(struct intel_dp *intel_dp)
 {
        struct intel_connector *intel_connector = intel_dp->attached_connector;
                if (IS_ERR(intel_connector->edid))
                        return NULL;
 
-               return drm_edid_duplicate(intel_connector->edid);
+               return drm_edid_dup(intel_connector->edid);
        } else
-               return drm_get_edid(&intel_connector->base,
-                                   &intel_dp->aux.ddc);
+               return drm_edid_read_ddc(&intel_connector->base,
+                                        &intel_dp->aux.ddc);
 }
 
 static void
 intel_dp_update_dfp(struct intel_dp *intel_dp,
-                   const struct edid *edid)
+                   const struct drm_edid *drm_edid)
 {
        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,
 {
        struct drm_i915_private *i915 = dp_to_i915(intel_dp);
        struct intel_connector *connector = intel_dp->attached_connector;
-       struct edid *edid;
+       const struct drm_edid *drm_edid;
+       const struct edid *edid;
        bool vrr_capable;
 
        intel_dp_unset_edid(intel_dp);
-       edid = intel_dp_get_edid(intel_dp);
-       connector->detect_edid = edid;
+       drm_edid = intel_dp_get_edid(intel_dp);
+       connector->detect_edid = drm_edid;
+
+       /* Below we depend on display info having been updated */
+       drm_edid_connector_update(&connector->base, drm_edid);
 
        vrr_capable = intel_vrr_is_capable(connector);
        drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",
                    connector->base.base.id, connector->base.name, str_yes_no(vrr_capable));
        drm_connector_set_vrr_capable_property(&connector->base, vrr_capable);
 
-       intel_dp_update_dfp(intel_dp, edid);
+       intel_dp_update_dfp(intel_dp, drm_edid);
        intel_dp_update_420(intel_dp);
 
+       /* FIXME: Get rid of drm_edid_raw() */
+       edid = drm_edid_raw(drm_edid);
        if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
                intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
                intel_dp->has_audio = drm_detect_monitor_audio(edid);
        struct intel_connector *connector = intel_dp->attached_connector;
 
        drm_dp_cec_unset_edid(&intel_dp->aux);
-       kfree(connector->detect_edid);
+       drm_edid_free(connector->detect_edid);
        connector->detect_edid = NULL;
 
        intel_dp->has_hdmi_sink = false;
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
        struct intel_connector *intel_connector = to_intel_connector(connector);
-       struct edid *edid;
-       int num_modes = 0;
+       int num_modes;
 
-       edid = intel_connector->detect_edid;
-       if (edid)
-               num_modes = intel_connector_update_modes(connector, edid);
+       /* drm_edid_connector_update() done in ->detect() or ->force() */
+       num_modes = drm_edid_connector_add_modes(connector);
 
        /* Also add fixed mode, which may or may not be present in EDID */
        if (intel_dp_is_edp(intel_attached_dp(intel_connector)))
        if (num_modes)
                return num_modes;
 
-       if (!edid) {
+       if (!intel_connector->detect_edid) {
                struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
                struct drm_display_mode *mode;
 
        struct drm_display_mode *fixed_mode;
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        bool has_dpcd;
-       struct edid *edid;
+       const struct drm_edid *drm_edid;
 
        if (!intel_dp_is_edp(intel_dp))
                return true;
        }
 
        mutex_lock(&dev_priv->drm.mode_config.mutex);
-       edid = drm_get_edid(connector, &intel_dp->aux.ddc);
-       if (!edid) {
+       drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);
+       if (!drm_edid) {
+               const struct edid *edid;
+
                /* Fallback to EDID from ACPI OpRegion, if any */
+               /* FIXME: Make intel_opregion_get_edid() return drm_edid */
                edid = intel_opregion_get_edid(intel_connector);
-               if (edid)
+               if (edid) {
+                       drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
                        drm_dbg_kms(&dev_priv->drm,
                                    "[CONNECTOR:%d:%s] Using OpRegion EDID\n",
                                    connector->base.id, connector->name);
-       }
-       if (edid) {
-               if (drm_add_edid_modes(connector, edid)) {
-                       drm_connector_update_edid_property(connector, edid);
-               } else {
                        kfree(edid);
-                       edid = ERR_PTR(-EINVAL);
+               }
+       }
+       if (drm_edid) {
+               if (drm_edid_connector_update(connector, drm_edid) ||
+                   !drm_edid_connector_add_modes(connector)) {
+                       drm_edid_connector_update(connector, NULL);
+                       drm_edid_free(drm_edid);
+                       drm_edid = ERR_PTR(-EINVAL);
                }
        } else {
-               edid = ERR_PTR(-ENOENT);
+               drm_edid = ERR_PTR(-ENOENT);
        }
-       intel_connector->edid = edid;
+       intel_connector->edid = drm_edid;
 
-       intel_bios_init_panel_late(dev_priv, &intel_connector->panel,
-                                  encoder->devdata, IS_ERR(edid) ? NULL : edid);
+       intel_bios_init_panel_late(dev_priv, &intel_connector->panel, encoder->devdata,
+                                  IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
 
        intel_panel_add_edid_fixed_modes(intel_connector, true);
 
 
        intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
        intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
 
-       kfree(to_intel_connector(connector)->detect_edid);
+       drm_edid_free(to_intel_connector(connector)->detect_edid);
        to_intel_connector(connector)->detect_edid = NULL;
 }
 
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
        intel_wakeref_t wakeref;
-       struct edid *edid;
+       const struct drm_edid *drm_edid;
+       const struct edid *edid;
        bool connected = false;
        struct i2c_adapter *i2c;
 
 
        i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 
-       edid = drm_get_edid(connector, i2c);
+       drm_edid = drm_edid_read_ddc(connector, i2c);
 
-       if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+       if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {
                drm_dbg_kms(&dev_priv->drm,
                            "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
                intel_gmbus_force_bit(i2c, true);
-               edid = drm_get_edid(connector, i2c);
+               drm_edid = drm_edid_read_ddc(connector, i2c);
                intel_gmbus_force_bit(i2c, false);
        }
 
-       to_intel_connector(connector)->detect_edid = edid;
+       /* Below we depend on display info having been updated */
+       drm_edid_connector_update(connector, drm_edid);
+
+       to_intel_connector(connector)->detect_edid = drm_edid;
+
+       /* FIXME: Get rid of drm_edid_raw() */
+       edid = drm_edid_raw(drm_edid);
        if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
                intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
                intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-       struct edid *edid;
-
-       edid = to_intel_connector(connector)->detect_edid;
-       if (edid == NULL)
-               return 0;
-
-       return intel_connector_update_modes(connector, edid);
+       /* drm_edid_connector_update() done in ->detect() or ->force() */
+       return drm_edid_connector_add_modes(connector);
 }
 
 static struct i2c_adapter *
 
        struct intel_connector *intel_connector = to_intel_connector(connector);
 
        /* use cached edid if we have one */
-       if (!IS_ERR_OR_NULL(intel_connector->edid))
-               return drm_add_edid_modes(connector, intel_connector->edid);
+       if (!IS_ERR_OR_NULL(intel_connector->edid)) {
+               drm_edid_connector_update(connector, intel_connector->edid);
+
+               return drm_edid_connector_add_modes(connector);
+       }
 
        return intel_panel_get_modes(intel_connector);
 }
        struct intel_connector *intel_connector;
        struct drm_connector *connector;
        struct drm_encoder *encoder;
-       struct edid *edid;
+       const struct drm_edid *drm_edid;
        i915_reg_t lvds_reg;
        u32 lvds;
        u8 pin;
         * preferred mode is the right one.
         */
        mutex_lock(&dev_priv->drm.mode_config.mutex);
-       if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
+       if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {
+               const struct edid *edid;
+
+               /* FIXME: Make drm_get_edid_switcheroo() return drm_edid */
                edid = drm_get_edid_switcheroo(connector,
-                                   intel_gmbus_get_adapter(dev_priv, pin));
-       else
-               edid = drm_get_edid(connector,
-                                   intel_gmbus_get_adapter(dev_priv, pin));
-       if (edid) {
-               if (drm_add_edid_modes(connector, edid)) {
-                       drm_connector_update_edid_property(connector,
-                                                               edid);
-               } else {
+                                              intel_gmbus_get_adapter(dev_priv, pin));
+               if (edid) {
+                       drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
                        kfree(edid);
-                       edid = ERR_PTR(-EINVAL);
+               } else {
+                       drm_edid = NULL;
+               }
+       } else {
+               drm_edid = drm_edid_read_ddc(connector,
+                                            intel_gmbus_get_adapter(dev_priv, pin));
+       }
+       if (drm_edid) {
+               if (drm_edid_connector_update(connector, drm_edid) ||
+                   !drm_edid_connector_add_modes(connector)) {
+                       drm_edid_connector_update(connector, NULL);
+                       drm_edid_free(drm_edid);
+                       drm_edid = ERR_PTR(-EINVAL);
                }
        } else {
-               edid = ERR_PTR(-ENOENT);
+               drm_edid = ERR_PTR(-ENOENT);
        }
-       intel_connector->edid = edid;
+       intel_connector->edid = drm_edid;
 
        intel_bios_init_panel_late(dev_priv, &intel_connector->panel, NULL,
-                                  IS_ERR(edid) ? NULL : edid);
+                                  IS_ERR_OR_NULL(drm_edid) ? NULL : drm_edid_raw(drm_edid));
 
        /* Try EDID first */
        intel_panel_add_edid_fixed_modes(intel_connector, true);