diff mbox

[RFC,15/18] drm/i915: MEDIA_RR support in DSI DRRS module

Message ID 1435326722-24633-16-git-send-email-ramalingam.c@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ramalingam C June 26, 2015, 1:51 p.m. UTC
Content based DRRS support is implemented in
DSI DRRS module also.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_dsi_drrs.c |   60 +++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dsi_drrs.c b/drivers/gpu/drm/i915/intel_dsi_drrs.c
index d4bb70a..4ff06b8 100644
--- a/drivers/gpu/drm/i915/intel_dsi_drrs.c
+++ b/drivers/gpu/drm/i915/intel_dsi_drrs.c
@@ -19,6 +19,7 @@ 
 
 #include "intel_drv.h"
 #include "intel_dsi.h"
+#include "intel_drrs.h"
 
 /*
  * VLV and CHV platform code
@@ -50,9 +51,19 @@  static void intel_mipi_drrs_work_fn(struct work_struct *__work)
 	struct dsi_drrs *dsi_drrs = &intel_dsi->dsi_drrs;
 	struct dsi_mnp *dsi_mnp;
 	struct drm_display_mode *prev_mode = NULL;
+	bool resume_idleness_detection = false;
 	bool fallback_attempt = false;
 	int ret, retry_cnt = 3;
 
+	if (work->target_rr_type == DRRS_MEDIA_RR) {
+		ret = dsi_drrs->ops->mnp_calculate_for_mode(
+				intel_encoder, &dsi_drrs->mnp[DRRS_MEDIA_RR],
+				drrs->connector->panel.target_mode);
+		if (ret < 0) {
+			DRM_ERROR("mnp calculation failed\n");
+			goto out;
+		}
+	}
 init:
 	dsi_mnp = &dsi_drrs->mnp[work->target_rr_type];
 	DRM_DEBUG("Refresh rate Type: %d-->%d\n",
@@ -60,6 +71,10 @@  init:
 						work->target_rr_type);
 	DRM_DEBUG("Target RR: %d\n", work->target_mode->vrefresh);
 
+	if (drrs->drrs_state.current_rr_type == DRRS_MEDIA_RR &&
+			work->target_rr_type == DRRS_HIGH_RR)
+		resume_idleness_detection = true;
+
 retry:
 	if (!intel_crtc || !intel_crtc->active)
 		goto out;
@@ -87,6 +102,11 @@  retry:
 
 		/* TODO: Update drain ladency with watermark */
 
+		if (resume_idleness_detection) {
+			intel_disable_idleness_drrs(drrs);
+			intel_enable_idleness_drrs(drrs);
+		}
+
 	} else if (ret == -ETIMEDOUT && retry_cnt) {
 
 		/* Timed out. But still attempts are allowed */
@@ -111,10 +131,14 @@  retry:
 		work->target_rr_type = drrs->drrs_state.target_rr_type;
 		drm_mode_destroy(intel_encoder->base.dev, work->target_mode);
 
-		if (work->target_rr_type == DRRS_HIGH_RR)
+		if (work->target_rr_type == DRRS_HIGH_RR) {
 			prev_mode = drrs->connector->panel.fixed_mode;
-		else if (work->target_rr_type == DRRS_LOW_RR)
+			resume_idleness_detection = true;
+		} else if (work->target_rr_type == DRRS_LOW_RR) {
 			prev_mode = drrs->connector->panel.downclock_mode;
+		} else if (work->target_rr_type == DRRS_MEDIA_RR) {
+			prev_mode = drrs->connector->panel.target_mode;
+		}
 
 		work->target_mode = drm_mode_duplicate(intel_encoder->base.dev,
 								prev_mode);
@@ -137,6 +161,37 @@  out:
 	work->work_completed = true;
 }
 
+/*
+ * As a part of Media playback request filtering
+ * we validate the incoming request wrt deferred works
+ * of MIPI PLL programming
+ */
+bool intel_dsi_is_mp_drrs_req(struct i915_drrs *drrs,
+					struct drm_display_mode *mode)
+{
+	struct intel_dsi *intel_dsi =
+			enc_to_intel_dsi(&drrs->connector->encoder->base);
+	struct dsi_drrs *dsi_drrs = &intel_dsi->dsi_drrs;
+	struct intel_mipi_drrs_work *work = dsi_drrs->mipi_drrs_work;
+	bool ret = false;
+
+	if (work_busy(&work->work.work)) {
+		if (work->target_mode->vrefresh != mode->vrefresh ||
+			drrs->drrs_state.current_rr_type != DRRS_MEDIA_RR)
+
+			/*
+			 * First condition: Deferred work is in place to change
+			 * the DRRS state. Hence this call is valid Media
+			 * playback DRRS request.
+			 *
+			 * Second Condition: Might be same as deffered work but
+			 * this is from media playback request. So honor it.
+			 */
+			ret = true;
+	}
+	return ret;
+}
+
 /* Whether DRRS_HR_STATE is pending in the dsi deferred work */
 bool intel_dsi_is_drrs_hr_state_pending(struct i915_drrs *drrs)
 {
@@ -350,6 +405,7 @@  struct drrs_encoder_ops drrs_dsi_ops = {
 	.exit = intel_dsi_drrs_exit,
 	.set_drrs_state = intel_dsi_set_drrs_state,
 	.is_drrs_hr_state_pending = intel_dsi_is_drrs_hr_state_pending,
+	.is_mp_drrs_req = intel_dsi_is_mp_drrs_req,
 };
 
 /* Call back Function for Intel_drrs module to get the dsi func ptr */