diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 677293d..dbdba44 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -948,10 +948,12 @@ enum drrs_support_type {
  * Different DRRS States:
  * DRRS_HIGH_RR	: Refreshrate of Fixed mode. [Maximum Vrefresh]
  * DRRS_LOW_RR	: Refreshrate of Downclock mode. [Minimum vrefresh]
+ * DRRS_MEDIA_RR: Refreshrate of requested from userspace. [<Max && >= Min]
  */
 enum drrs_refresh_rate_type {
 	DRRS_HIGH_RR,
 	DRRS_LOW_RR,
+	DRRS_MEDIA_RR,
 	DRRS_MAX_RR,
 };
 
@@ -983,6 +985,8 @@ struct drrs_encoder_ops {
 	void (*exit)(struct i915_drrs *);
 	void (*set_drrs_state)(struct i915_drrs *);
 	bool (*is_drrs_hr_state_pending)(struct i915_drrs *);
+	bool (*is_mp_drrs_req)(struct i915_drrs *,
+						struct drm_display_mode *);
 };
 
 struct i915_drrs {
@@ -992,6 +996,9 @@ struct i915_drrs {
 	/* Whether DRRS is supported on this Panel */
 	bool has_drrs;
 
+	/* Flag to resume the Idleness DRRS from Media Playback */
+	bool resume_idleness_detection;
+
 	/* Holds the DRRS state machine states */
 	struct drrs_info drrs_state;
 
diff --git a/drivers/gpu/drm/i915/intel_drrs.c b/drivers/gpu/drm/i915/intel_drrs.c
index 2901832..7f66be4 100644
--- a/drivers/gpu/drm/i915/intel_drrs.c
+++ b/drivers/gpu/drm/i915/intel_drrs.c
@@ -111,6 +111,13 @@ bool is_cloned_mode_active(struct drm_device *dev)
 	return false;
 }
 
+static inline bool
+is_media_playback_drrs_in_progress(struct drrs_info *drrs_state)
+{
+	return drrs_state->current_rr_type == DRRS_MEDIA_RR ||
+		drrs_state->target_rr_type == DRRS_MEDIA_RR;
+}
+
 void intel_set_drrs_state(struct i915_drrs *drrs)
 {
 	struct drrs_info *drrs_state;
@@ -157,7 +164,8 @@ void intel_set_drrs_state(struct i915_drrs *drrs)
 		return;
 	}
 
-	if (drrs_state->target_rr_type == drrs_state->current_rr_type) {
+	if (drrs_state->target_rr_type == drrs_state->current_rr_type &&
+			drrs_state->current_rr_type != DRRS_MEDIA_RR) {
 		DRM_INFO("Requested for previously set RR. Ignoring\n");
 		return;
 	}
@@ -170,19 +178,24 @@ void intel_set_drrs_state(struct i915_drrs *drrs)
 		 * As only DSI has SEAMLESS_DRRS_SUPPORT_SW.
 		 */
 		/*
-		 * TODO: Protect the access to the crtc mode with corresponding
+		 * Protect the access to the crtc mode with corresponding
 		 * mutex in case of Idleness DRRS. As media playback update
 		 * will happen under crtc modeset lock protection
 		 */
-		drm_modeset_lock(&intel_crtc->base.mutex, NULL);
+		if (!is_media_playback_drrs_in_progress(drrs_state))
+			drm_modeset_lock(&intel_crtc->base.mutex, NULL);
 		intel_crtc->base.mode.clock = target_mode->clock;
 		intel_crtc->base.mode.vrefresh = target_mode->vrefresh;
 		intel_crtc->config->base.adjusted_mode.clock =
 							target_mode->clock;
 		intel_crtc->config->base.adjusted_mode.vrefresh =
 							target_mode->vrefresh;
-		drm_modeset_unlock(&intel_crtc->base.mutex);
+		if (!is_media_playback_drrs_in_progress(drrs_state))
+			drm_modeset_unlock(&intel_crtc->base.mutex);
 
+		if (drrs_state->current_rr_type == DRRS_MEDIA_RR &&
+				drrs_state->target_rr_type == DRRS_HIGH_RR)
+			drrs->resume_idleness_detection = true;
 		drrs_state->current_rr_type = drrs_state->target_rr_type;
 		DRM_INFO("Refresh Rate set to : %dHz\n", refresh_rate);
 	}
@@ -203,6 +216,11 @@ static void intel_idleness_drrs_work_fn(struct work_struct *__work)
 		return;
 
 	mutex_lock(&drrs->drrs_mutex);
+	if (is_media_playback_drrs_in_progress(&drrs->drrs_state)) {
+		mutex_unlock(&drrs->drrs_mutex);
+		return;
+	}
+
 	if (panel->target_mode != NULL)
 		DRM_ERROR("FIXME: We shouldn't be here\n");
 
@@ -229,7 +247,7 @@ static void intel_cancel_idleness_drrs_work(struct i915_drrs *drrs, bool sync)
 	drrs->connector->panel.target_mode = NULL;
 }
 
-static void intel_enable_idleness_drrs(struct i915_drrs *drrs)
+void intel_enable_idleness_drrs(struct i915_drrs *drrs)
 {
 	bool force_enable_drrs = false;
 
@@ -240,6 +258,11 @@ static void intel_enable_idleness_drrs(struct i915_drrs *drrs)
 	if (drrs->is_clone)
 		return;
 
+	if (is_media_playback_drrs_in_progress(&drrs->drrs_state)) {
+		mutex_unlock(&drrs->drrs_mutex);
+		return;
+	}
+
 	/* Capturing the deferred request for disable_drrs */
 	if (drrs->drrs_state.type == SEAMLESS_DRRS_SUPPORT_SW &&
 				drrs->encoder_ops->is_drrs_hr_state_pending) {
@@ -267,6 +290,12 @@ void intel_disable_idleness_drrs(struct i915_drrs *drrs)
 	struct intel_panel *panel;
 
 	mutex_lock(&drrs->drrs_mutex);
+
+	if (is_media_playback_drrs_in_progress(&drrs->drrs_state)) {
+		mutex_unlock(&drrs->drrs_mutex);
+		return;
+	}
+
 	panel = &drrs->connector->panel;
 
 	/* as part of disable DRRS, reset refresh rate to HIGH_RR */
@@ -301,7 +330,6 @@ void intel_drrs_invalidate(struct drm_device *dev,
 	int pipe;
 	int index;
 
-
 	for (pipe = 0; pipe < 4; pipe++) {
 		if (frontbuffer_bits & (0xf << (16 * pipe))) {
 			index = get_drrs_struct_index_for_pipe(dev_priv, pipe);
@@ -375,6 +403,126 @@ void intel_drrs_flush(struct drm_device *dev,
 	}
 }
 
+/*
+ * Handles the userspace request for MEDIA_RR.
+ */
+int intel_media_playback_drrs_configure(struct intel_crtc *crtc,
+					struct drm_display_mode *mode)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_drrs *drrs;
+	struct drrs_info *drrs_state;
+	struct intel_panel *panel;
+	struct drm_crtc *tmp_crtc = NULL;
+	int refresh_rate = mode->vrefresh;
+	int index, crtc_cnt = 0;
+
+	index = get_drrs_struct_index_for_crtc(dev_priv, crtc);
+	if (index < 0)
+		return -EINVAL;
+
+	drrs = dev_priv->drrs[index];
+	if (!drrs || !drrs->has_drrs) {
+		DRM_ERROR("DRRS is not supported\n");
+		return -EPERM;
+	}
+
+	drrs_state = &drrs->drrs_state;
+	panel = &drrs->connector->panel;
+
+	if (refresh_rate < panel->downclock_mode->vrefresh &&
+			refresh_rate > panel->fixed_mode->vrefresh) {
+		DRM_ERROR("Invalid refresh_rate\n");
+		return -EINVAL;
+	}
+
+	intel_cancel_idleness_drrs_work(drrs, false);
+
+	mutex_lock(&drrs->drrs_mutex);
+
+	if (refresh_rate == panel->fixed_mode->vrefresh) {
+		if (drrs_state->current_rr_type == DRRS_MEDIA_RR) {
+
+			/* DRRS_MEDIA_RR -> DRRS_HIGH_RR */
+			if (panel->target_mode)
+				drm_mode_destroy(dev, panel->target_mode);
+			panel->target_mode = panel->fixed_mode;
+			drrs_state->target_rr_type = DRRS_HIGH_RR;
+		} else {
+
+			/*
+			 * Invalid Media Playback DRRS request.
+			 * Resume the Idleness Detection
+			 */
+			DRM_ERROR("Invalid Entry req for mode DRRS_MEDIA_RR\n");
+			mutex_unlock(&drrs->drrs_mutex);
+			intel_disable_idleness_drrs(drrs);
+			intel_enable_idleness_drrs(drrs);
+			return 0;
+		}
+	} else {
+		drrs->is_clone = false;
+		list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list,
+									head) {
+			if (intel_crtc_active(tmp_crtc)) {
+				if (crtc_cnt) {
+					DRM_DEBUG_KMS(
+						"more than one pipe active\n");
+					drrs->is_clone = true;
+					break;
+				}
+				crtc_cnt++;
+			}
+		}
+
+		if (drrs->is_clone) {
+			if (panel->target_mode &&
+				drrs_state->current_rr_type == DRRS_MEDIA_RR)
+				drm_mode_destroy(dev, panel->target_mode);
+			panel->target_mode = panel->fixed_mode;
+			drrs_state->target_rr_type = DRRS_HIGH_RR;
+			goto set_state;
+		}
+
+		drrs_state->target_rr_type = DRRS_MEDIA_RR;
+
+		if (drrs_state->current_rr_type == DRRS_MEDIA_RR) {
+
+			/* Refresh rate change in Media playback DRRS */
+			if (refresh_rate == panel->target_mode->vrefresh) {
+				DRM_DEBUG("Request for current RR.<%d>\n",
+					panel->target_mode->vrefresh);
+				mutex_unlock(&drrs->drrs_mutex);
+				return 0;
+			}
+			panel->target_mode->vrefresh = refresh_rate;
+		} else {
+
+			/* Entering MEDIA Playback DRRS state */
+			panel->target_mode = drm_mode_duplicate(dev, mode);
+		}
+
+		panel->target_mode->clock = mode->vrefresh * mode->vtotal *
+							mode->htotal / 1000;
+	}
+
+set_state:
+	DRM_DEBUG("cur_rr_type: %d, target_rr_type: %d, target_rr: %d\n",
+						drrs_state->current_rr_type,
+						drrs_state->target_rr_type,
+						panel->target_mode->vrefresh);
+
+	intel_set_drrs_state(drrs);
+	mutex_unlock(&drrs->drrs_mutex);
+
+	if (drrs->resume_idleness_detection) {
+		intel_disable_idleness_drrs(drrs);
+		intel_enable_idleness_drrs(drrs);
+	}
+	return 0;
+}
+
 /* Idleness detection logic is initialized */
 int intel_drrs_idleness_detection_init(struct i915_drrs *drrs)
 {
@@ -480,6 +628,7 @@ int intel_drrs_init(struct drm_device *dev,
 	drrs->has_drrs = true;
 	to_intel_crtc(intel_encoder->base.crtc)->config->has_drrs = true;
 	mutex_init(&drrs->drrs_mutex);
+	drrs->resume_idleness_detection = false;
 	drrs->drrs_state.current_rr_type = DRRS_HIGH_RR;
 	DRM_INFO("SEAMLESS DRRS supported on this panel.\n");
 
diff --git a/drivers/gpu/drm/i915/intel_drrs.h b/drivers/gpu/drm/i915/intel_drrs.h
index a07f023..7f9985c0 100644
--- a/drivers/gpu/drm/i915/intel_drrs.h
+++ b/drivers/gpu/drm/i915/intel_drrs.h
@@ -26,7 +26,10 @@ int get_drrs_struct_index_for_crtc(struct drm_i915_private *dev_priv,
 int get_drrs_struct_index_for_connector(struct drm_i915_private *dev_priv,
 				struct intel_connector *intel_connector);
 int get_free_drrs_struct_index(struct drm_i915_private *dev_priv);
-
+void intel_disable_idleness_drrs(struct i915_drrs *drrs);
+void intel_enable_idleness_drrs(struct i915_drrs *drrs);
+int intel_media_playback_drrs_configure(struct intel_crtc *crtc,
+					struct drm_display_mode *mode);
 int intel_drrs_init(struct drm_device *dev,
 			struct intel_connector *intel_connector,
 				struct drm_display_mode *fixed_mode);
