diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6f3af15..eec32ed 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1614,6 +1614,13 @@ typedef struct drm_i915_private {
 	 */
 	struct drm_property *input_size_property;
 
+	/*
+	 * Property to dynamically vary the size of the
+	 * borders. This will indirectly control the size
+	 * of the display window i.e Panel fitter output
+	 */
+	struct drm_property *output_border_property;
+
 	uint32_t hw_context_size;
 	struct list_head context_list;
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7149123..a217f25 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10447,7 +10447,23 @@ static int intel_crtc_set_property(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	int ret = -ENOENT;
+
+	if (property == dev_priv->output_border_property) {
+		if ((val == (uint64_t)intel_crtc->border_size) &&
+		    (((val >> 32) & 0x1) == intel_crtc->pfit_enabled))
+			return 0;
+
+		intel_crtc->border_size = (uint32_t)val;
+		intel_crtc->pfit_enabled = (val >> 32) & 0x1;
+		if ((intel_crtc->border_size != 0) &&
+		    (!intel_crtc->pfit_enabled)) {
+			DRM_ERROR("Wrong setting, expect Pfit to be enabled when "
+				  "applying borders\n");
+			return -EINVAL;
+		}
+
+		goto done;
+	}
 
 	if (property == dev_priv->input_size_property) {
 		int new_width = (int)((val >> 16) & 0xffff); @@ -10488,7 +10504,13 @@ static int intel_crtc_set_property(struct drm_crtc *crtc,
 		return 0;
 	}
 
-	return ret;
+	return -EINVAL;
+
+done:
+	if (crtc)
+		intel_crtc_restore_mode(crtc);
+
+	return 0;
 }
 
 static const struct drm_crtc_funcs intel_crtc_funcs = { @@ -10641,12 +10663,23 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 
 	if (!dev_priv->input_size_property)
 		dev_priv->input_size_property =
-			drm_property_create_range(dev, 0, "input size", 0, 0xFFFFFFFF);
+			drm_property_create_range(dev, 0, "input size",
+						0, 0xFFFFFFFF);
 
 	if (dev_priv->input_size_property)
 		drm_object_attach_property(&intel_crtc->base.base,
 					   dev_priv->input_size_property,
 					   0);
+
+	if (!dev_priv->output_border_property)
+		dev_priv->output_border_property =
+			drm_property_create_range(dev, 0, "border size",
+						0, (uint64_t)0x1FFFFFFFF);
+
+	if (dev_priv->output_border_property)
+		drm_object_attach_property(&intel_crtc->base.base,
+					   dev_priv->output_border_property,
+					   0);
 }
 
 enum pipe intel_get_pipe_from_connector(struct intel_connector *connector) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5360d16..3cfc9da 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -387,6 +387,11 @@ struct intel_crtc {
 	bool cpu_fifo_underrun_disabled;
 	bool pch_fifo_underrun_disabled;
 
+	/* for forceful enabling of panel fitter */
+	bool pfit_enabled;
+	/* border info for the output/display window */
+	uint32_t border_size;
+
 	/* per-pipe watermark state */
 	struct {
 		/* watermarks currently being used  */ diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index cb05840..86a486e 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -29,10 +29,25 @@
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+/* Max Downscale ratio of 1.125, expressed in 1.12 fixed point format 
+*/ #define MAX_DOWNSCALE_RATIO  (0x9 << 9)
 
 #include <linux/moduleparam.h>
 #include "intel_drv.h"
 
+static inline u32 panel_fitter_scaling(u32 source, u32 target) {
+	/*
+	 * Floating point operation is not supported. So the FACTOR
+	 * is defined, which can avoid the floating point computation
+	 * when calculating the panel ratio.
+	 */
+#define ACCURACY 12
+#define FACTOR (1 << ACCURACY)
+	u32 ratio = source * FACTOR / target;
+	return (FACTOR * ratio + FACTOR/2) / FACTOR; }
+
 void
 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
 		       struct drm_display_mode *adjusted_mode) @@ -42,6 +57,60 @@ intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
 	drm_mode_set_crtcinfo(adjusted_mode, 0);  }
 
