diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 18d9da53282b..c4c8590972b4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2151,6 +2151,8 @@ struct intel_cdclk_state {
 	unsigned int cdclk, vco, ref;
 };
 
+struct intel_panel;
+
 struct drm_i915_private {
 	struct drm_device drm;
 
@@ -2200,6 +2202,7 @@ struct drm_i915_private {
 	struct i915_gem_context *kernel_context;
 	struct intel_engine_cs *engine[I915_NUM_ENGINES];
 	struct i915_vma *semaphore;
+	struct intel_panel *panel;
 
 	struct drm_dma_handle *status_page_dmah;
 	struct resource mch_res;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f17275519484..c40939be9599 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2891,6 +2891,9 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 		return;
 	}
 
+	intel_panel_set_orientation_from_crtc(dev_priv->panel, intel_crtc,
+					      plane_config->panel_orientation);
+
 	plane_state->src_x = 0;
 	plane_state->src_y = 0;
 	plane_state->src_w = fb->width << 16;
@@ -7523,6 +7526,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
 			plane_config->tiling = I915_TILING_X;
 			fb->modifier = I915_FORMAT_MOD_X_TILED;
 		}
+
+		if (val & DISPPLANE_ROTATE_180)
+			plane_config->panel_orientation =
+				DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
 	}
 
 	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
@@ -8576,6 +8583,24 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 		goto error;
 	}
 
+	/* The rotation is used to *correct* for the panel orientation */
+	switch (val & PLANE_CTL_ROTATE_MASK) {
+	case PLANE_CTL_ROTATE_0:
+		break;
+	case PLANE_CTL_ROTATE_90:
+		plane_config->panel_orientation =
+			DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
+		break;
+	case PLANE_CTL_ROTATE_180:
+		plane_config->panel_orientation =
+			DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+		break;
+	case PLANE_CTL_ROTATE_270:
+		plane_config->panel_orientation =
+			DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
+		break;
+	}
+
 	base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000;
 	plane_config->base = base;
 
@@ -8661,6 +8686,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
 			plane_config->tiling = I915_TILING_X;
 			fb->modifier = I915_FORMAT_MOD_X_TILED;
 		}
+
+		if (val & DISPPLANE_ROTATE_180)
+			plane_config->panel_orientation =
+				DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
 	}
 
 	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
@@ -14578,7 +14607,9 @@ int intel_modeset_init(struct drm_device *dev)
 	drm_modeset_unlock_all(dev);
 
 	for_each_intel_crtc(dev, crtc) {
-		struct intel_initial_plane_config plane_config = {};
+		struct intel_initial_plane_config plane_config = {
+			.panel_orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL,
+		};
 
 		if (!crtc->active)
 			continue;
@@ -14600,6 +14631,12 @@ int intel_modeset_init(struct drm_device *dev)
 		intel_find_initial_plane_obj(crtc, &plane_config);
 	}
 
+	/*
+	 * Init panel orientation prop now that intel_find_initial_plane_obj()
+	 * has had a chance to set panel orientation.
+	 */
+	intel_panel_init_orientation_prop(dev_priv->panel);
+
 	/*
 	 * Make sure hardware watermarks really match the state we read out.
 	 * Note that we need to do this after reconstructing the BIOS fb's
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fa47285918f4..50fa0eeca655 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -447,6 +447,7 @@ struct intel_initial_plane_config {
 	unsigned int tiling;
 	int size;
 	u32 base;
+	int panel_orientation; /* DRM_MODE_PANEL_ORIENTATION_* */
 };
 
 #define SKL_MIN_SRC_W 8
@@ -1703,6 +1704,10 @@ extern struct drm_display_mode *intel_find_panel_downclock(
 				struct drm_i915_private *dev_priv,
 				struct drm_display_mode *fixed_mode,
 				struct drm_connector *connector);
+void intel_panel_set_orientation_from_crtc(struct intel_panel *panel,
+					   struct intel_crtc *intel_crtc,
+					   int orientation);
+void intel_panel_init_orientation_prop(struct intel_panel *panel);
 
 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
 int intel_backlight_device_register(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 72f8cbb237b1..f28dc96181ef 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1921,11 +1921,44 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
 	}
 }
 
+void intel_panel_set_orientation_from_crtc(struct intel_panel *panel,
+					   struct intel_crtc *intel_crtc,
+					   int orientation)
+{
+	struct intel_connector *panel_conn;
+
+	if (!panel)
+		return;
+
+	panel_conn = container_of(panel, struct intel_connector, panel);
+	if (panel_conn->base.state->crtc == &intel_crtc->base)
+		panel_conn->base.display_info.panel_orientation = orientation;
+}
+
+void intel_panel_init_orientation_prop(struct intel_panel *panel)
+{
+	struct intel_connector *panel_conn;
+
+	if (!panel || !panel->fixed_mode)
+		return;
+
+	panel_conn = container_of(panel, struct intel_connector, panel);
+	drm_connector_init_panel_orientation_property(&panel_conn->base,
+		panel->fixed_mode->hdisplay, panel->fixed_mode->vdisplay);
+}
+
 int intel_panel_init(struct intel_panel *panel,
 		     struct drm_display_mode *fixed_mode,
 		     struct drm_display_mode *alt_fixed_mode,
 		     struct drm_display_mode *downclock_mode)
 {
+	struct intel_connector *intel_connector =
+		container_of(panel, struct intel_connector, panel);
+	struct drm_i915_private *dev_priv = to_i915(intel_connector->base.dev);
+
+	if (!dev_priv->panel)
+		dev_priv->panel = panel;
+
 	intel_panel_init_backlight_funcs(panel);
 
 	panel->fixed_mode = fixed_mode;
