diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 5a1192496d49..64135cd2302e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -2662,6 +2662,189 @@ enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
+/*
+ * Average pixels per millimeter and centimeter for a circa 2020 display
+ */
+#define VMW_FAKE_PPMM 4
+#define VMW_FAKE_PPCM 40
+
+static void vmw_mode_to_timing(const struct drm_display_mode *mode,
+			       struct detailed_timing *timing)
+{
+	struct detailed_pixel_timing *dpt = &timing->data.pixel_data;
+
+	const u8 hblank = (mode->htotal - mode->hdisplay);
+	const u8 hfront = (mode->hsync_start - mode->hdisplay);
+	const u8 hsync  = (mode->hsync_end - mode->hsync_start);
+
+	const u8 vblank = (mode->vtotal - mode->vdisplay);
+	const u8 vfront = (mode->vsync_start - mode->vdisplay);
+	const u8 vsync  = (mode->vsync_end - mode->vsync_start);
+
+	const unsigned int wmm = mode->hdisplay / VMW_FAKE_PPMM;
+	const unsigned int hmm = mode->vdisplay / VMW_FAKE_PPMM;
+
+	timing->pixel_clock = mode->clock / 10;
+	memset(dpt, 0, sizeof(*dpt));
+
+	// horizontal
+	dpt->hactive_lo = mode->hdisplay & 0xFF;
+	dpt->hblank_lo = hblank & 0xFF;
+
+	dpt->hactive_hblank_hi |= (mode->hdisplay >> 4) & 0xF0;
+	dpt->hactive_hblank_hi |= (hblank >> 8) & 0x0F;
+
+	dpt->hsync_offset_lo      = hfront & 0xFF;
+	dpt->hsync_pulse_width_lo =  hsync & 0xFF;
+
+	dpt->hsync_vsync_offset_pulse_width_hi |= (hfront >> 2) & 0xC0;
+	dpt->hsync_vsync_offset_pulse_width_hi |= (hsync  >> 4) & 0x30;
+
+	// vertical
+	dpt->vactive_lo = mode->vdisplay & 0xFF;
+	dpt->vactive_vblank_hi |= (mode->vdisplay >> 4) & 0xF0;
+
+	dpt->vblank_lo = vblank & 0xFF;
+	dpt->vactive_vblank_hi |= (vblank >> 8) & 0x0F;
+
+	dpt->vsync_offset_pulse_width_lo |= (vfront & 0x0F) << 4;
+	dpt->vsync_offset_pulse_width_lo |= (vsync  & 0x0F) << 0;
+
+	dpt->hsync_vsync_offset_pulse_width_hi |= (vfront >> 4) & 0x0C;
+	dpt->hsync_vsync_offset_pulse_width_hi |= (vsync  >> 8) & 0x03;
+
+	// physical sizes
+	dpt->width_mm_lo  = wmm & 0xFF;
+	dpt->height_mm_lo = hmm & 0xFF;
+	dpt->width_height_mm_hi |= (wmm >> 4) & 0xF0;
+	dpt->width_height_mm_hi |= (hmm >> 8) & 0x0F;
+
+	dpt->hborder = 0;
+	dpt->vborder = 0;
+	dpt->misc |= 0x18;
+	dpt->misc |= (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0x2 : 0;
+	dpt->misc |= (mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0x4 : 0;
+}
+
+/* Our encoded Plug & Play ID
+ * See: https://uefi.org/PNP_ACPI_Registry and https://uefi.org/PNP_ID_List
+ */
+static inline __be16 vmw_pnp_id(void)
+{
+	return cpu_to_be16((('V' - '@') << 10) |
+			   (('M' - '@') <<  5) |
+			   (('W' - '@') <<  0));
+}
+
+// For use with drm_edid_read_custom
+struct vmw_edid_read_custom_ctx {
+	struct drm_display_mode *pref_mode;
+	unsigned int unit; // display unit id
+};
+
+/*
+ * Fills in the fake EDID using the preferred mode.
+ * The signature must match the drm_edid_read_custom callback.
+ * Only supports the EDID base block. No extensions.
+ * See 'Vesa Enhanced EDID Standard Release A Revision 2' and
+ * 'VESA DMT Standard Version 1.0 Revision 13'.
+ */
+static
+int vmw_fill_fake_edid(void *context, u8 *buf, unsigned int block, size_t len)
+{
+	int checksum = 0;
+	struct edid *e = (struct edid *)buf;
+	const struct vmw_edid_read_custom_ctx *ctx = context;
+
+	if (block != 0)
+		return -ENOENT;
+	if (len != EDID_LENGTH)
+		return -EINVAL;
+
+	e->header[0] = 0;
+	memset(e->header + 1, 0xFF, 6);
+	e->header[7] = 0;
+
+	e->product_id.manufacturer_name = vmw_pnp_id();
+	e->mfg_year = 32; // 2022
+	e->mfg_week = 32;
+
+	e->prod_code[0] = 'V';
+	e->prod_code[1] = 'M';
+	e->serial = 0xABC0 | ctx->unit;
+
+	e->version = 1;
+	e->revision = 4;
+
+	e->input = DRM_EDID_INPUT_DIGITAL | DRM_EDID_DIGITAL_DEPTH_8;
+	e->width_cm = DIV_ROUND_CLOSEST(ctx->pref_mode->hdisplay, VMW_FAKE_PPCM);
+	e->height_cm = DIV_ROUND_CLOSEST(ctx->pref_mode->vdisplay, VMW_FAKE_PPCM);
+	e->gamma = 120; // 2.20
+	e->features = DRM_EDID_FEATURE_STANDARD_COLOR |
+			DRM_EDID_FEATURE_PREFERRED_TIMING |
+			DRM_EDID_FEATURE_RGB |
+			DRM_EDID_FEATURE_PM_ACTIVE_OFF;
+
+	// Standard sRGB color space
+	e->red_green_lo = 0xEE;
+	e->blue_white_lo = 0x91;
+	e->red_x = 0xA3;
+	e->red_y = 0x54;
+	e->green_x = 0x4C;
+	e->green_y = 0x99;
+	e->blue_x  = 0x26;
+	e->blue_y  = 0x0F;
+	e->white_x = 0x50;
+	e->white_y = 0x54;
+
+	e->established_timings.t1 = 0x21;
+	e->established_timings.t2 = 0x08;
+
+	e->standard_timings[0].hsize = 0x81;
+	e->standard_timings[0].vfreq_aspect =  0xC0; // 720p60
+
+	e->standard_timings[1].hsize = 0xD1;
+	e->standard_timings[1].vfreq_aspect =  0xC0; // 1080p60
+
+	e->standard_timings[2].hsize = 0x81;
+	e->standard_timings[2].vfreq_aspect =  0x80; // 1280x1024@60
+
+	e->standard_timings[3].hsize = 0xD1;
+	e->standard_timings[3].vfreq_aspect =  0x40; // 1920x1440@60
+
+	e->standard_timings[4].hsize = 0xE1;
+	e->standard_timings[4].vfreq_aspect =  0xC0; // 2048x1152@60
+
+	e->standard_timings[5].hsize = 0xA9;
+	e->standard_timings[5].vfreq_aspect =  0x40; // 1600x1200@60
+
+	e->standard_timings[6].hsize = 0xB3;
+	e->standard_timings[6].vfreq_aspect =  0x00; // 2048x1152@60
+
+	e->standard_timings[7].hsize = 0x95;
+	e->standard_timings[7].vfreq_aspect =  0x00; // 1440x900@60
+
+	// This is the preferred/native mode
+	vmw_mode_to_timing(ctx->pref_mode, &e->detailed_timings[0]);
+
+	memset(&e->detailed_timings[1], 0, 3 * sizeof(struct detailed_timing));
+
+	e->detailed_timings[1].data.other_data.type = EDID_DETAIL_MONITOR_NAME;
+	memcpy(e->detailed_timings[1].data.other_data.data.str.str,
+	       "VMware Screen", 13);
+
+	e->detailed_timings[2].data.other_data.type = 0x10;
+	e->detailed_timings[3].data.other_data.type = 0x10;
+
+	e->extensions = 0;
+
+	for (int i = 0; i < sizeof(struct edid) - 1; i++)
+		checksum += ((u8 *)e)[i];
+
+	e->checksum = 0x100 - checksum;
+	return 0;
+}
+
 /*
  * Common modes not present in the VESA DMT standard or assigned a VIC.
  */
@@ -2685,6 +2868,8 @@ int vmw_connector_get_modes(struct drm_connector *connector)
 	struct drm_device *dev = connector->dev;
 	struct vmw_private *dev_priv = vmw_priv(dev);
 	struct drm_display_mode *mode = NULL;
+	const  struct drm_edid *fake_edid;
+	struct vmw_edid_read_custom_ctx ctx;
 	u32 max_width;
 	u32 max_height;
 	u32 num_modes = 0;
@@ -2700,6 +2885,13 @@ int vmw_connector_get_modes(struct drm_connector *connector)
 	num_modes++;
 	drm_dbg_kms(dev, "preferred mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
 
+	// update EDID
+	ctx.pref_mode = mode;
+	ctx.unit = du->unit;
+	fake_edid = drm_edid_read_custom(connector, vmw_fill_fake_edid, &ctx);
+	drm_edid_connector_update(connector, fake_edid);
+	drm_edid_free(fake_edid);
+
 	/* Probe connector for all modes not exceeding our geom limits */
 	max_width  = dev_priv->texture_max_width;
 	max_height = dev_priv->texture_max_height;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 39949e0a493f..e6496e372993 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -516,6 +516,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
 				   dev->mode_config.suggested_x_property, 0);
 	drm_object_attach_property(&connector->base,
 				   dev->mode_config.suggested_y_property, 0);
+	drm_connector_attach_edid_property(connector);
 	if (dev_priv->implicit_placement_property)
 		drm_object_attach_property
 			(&connector->base,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 0f4bfd98480a..50c3d0ca4767 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -905,7 +905,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
 				   dev->mode_config.suggested_x_property, 0);
 	drm_object_attach_property(&connector->base,
 				   dev->mode_config.suggested_y_property, 0);
-
+	drm_connector_attach_edid_property(connector);
 	vmw_du_init(&sou->base);
 
 	return 0;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 82d18b88f4a7..f7b2dbe4ef5b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -1630,7 +1630,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
 				   dev->mode_config.suggested_x_property, 0);
 	drm_object_attach_property(&connector->base,
 				   dev->mode_config.suggested_y_property, 0);
-
+	drm_connector_attach_edid_property(connector);
 	vmw_du_init(&stdu->base);
 
 	return 0;
