diff mbox

[6/6] drm/i915: Adding support for DMRRS for media playback

Message ID 1384841225-4688-7-git-send-email-vandana.kannan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

vandana.kannan@intel.com Nov. 19, 2013, 6:07 a.m. UTC
From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch provides support for two additional DRRS refresh rates
which will be used for video playback use cases. When the playback
is at 24fps, player can indicate the DRRS to set 48Hz. Similarly
for playback of 25fps DRRS 50Hz is used. This helps in better
power saving in active use cases like video playback. This feature
is for PV2 and not for PV1.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c  |   36 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |    7 +++++++
 2 files changed, 43 insertions(+)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ef7c50d..673907c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3765,12 +3765,21 @@  intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 	}
 }
 
+static int
+get_drrs_pclk(struct drm_display_mode *fixed_mode, int refresh_rate)
+{
+	return (refresh_rate * fixed_mode->htotal * fixed_mode->vtotal) / 1000;
+}
+
 static void
 intel_dp_drrs_modelist_create(struct intel_digital_port *intel_dig_port,
 				struct drm_display_mode *fixed_mode,
 				struct drm_display_mode *lowest_mode)
 {
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	intel_dp->drrs_state.refresh_rate_array[DRRS_HIGH_RR] =
 							fixed_mode->vrefresh;
@@ -3779,6 +3788,29 @@  intel_dp_drrs_modelist_create(struct intel_digital_port *intel_dig_port,
 	intel_dp->drrs_state.refresh_rate_array[DRRS_LOW_RR] =
 							lowest_mode->vrefresh;
 	intel_dp->drrs_state.pixel_clock[DRRS_LOW_RR] = lowest_mode->clock;
+
+	/* Check if DMRRS is supported and create additional entries */
+	if (dev_priv->vbt.intel_dmrrs_enabled) {
+		if (lowest_mode->vrefresh < MEDIA_DMRRS_FREQ_2) {
+			intel_dp->drrs_state.refresh_rate_array[DRRS_50HZ_RR] =
+						MEDIA_DMRRS_FREQ_1;
+			intel_dp->drrs_state.pixel_clock[DRRS_50HZ_RR] =
+						get_drrs_pclk(fixed_mode,
+						MEDIA_DMRRS_FREQ_1);
+			intel_dp->drrs_state.refresh_rate_array[DRRS_48HZ_RR] =
+						MEDIA_DMRRS_FREQ_2;
+			intel_dp->drrs_state.pixel_clock[DRRS_48HZ_RR] =
+						get_drrs_pclk(fixed_mode,
+						MEDIA_DMRRS_FREQ_2);
+		} else if (lowest_mode->vrefresh < MEDIA_DMRRS_FREQ_1) {
+			intel_dp->drrs_state.refresh_rate_array[DRRS_50HZ_RR] =
+						MEDIA_DMRRS_FREQ_1;
+			intel_dp->drrs_state.pixel_clock[DRRS_50HZ_RR] =
+						get_drrs_pclk(fixed_mode,
+						MEDIA_DMRRS_FREQ_1);
+		}
+	} else
+		DRM_INFO("DMRRS not supported.\n");
 }
 
 void
@@ -3859,6 +3891,10 @@  intel_dp_attach_drrs_properties(struct intel_dp *intel_dp,
 								"high_rr"},
 		{ intel_dp->drrs_state.refresh_rate_array[DRRS_LOW_RR],
 								"low_rr"},
+		{ intel_dp->drrs_state.refresh_rate_array[DRRS_50HZ_RR],
+								"50hz_rr"},
+		{ intel_dp->drrs_state.refresh_rate_array[DRRS_48HZ_RR],
+								"48hz_rr"},
 		/**
 		 * add more entries if more DRRS RRs supported.
 		 * The no.of entries should be equal to
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7c22fcf..f0f944f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -451,6 +451,11 @@  struct intel_hdmi {
 #define DP_MAX_DOWNSTREAM_PORTS		0x10
 
 /**
++ * Media refresh rates for dynamic switching
++ */
+#define MEDIA_DMRRS_FREQ_1 50
+#define MEDIA_DMRRS_FREQ_2 48
+/**
  * This enum is used to indicate the DRRS support type.
  * The values of the enum map 1-to-1 with the values from VBT.
  */
@@ -467,6 +472,8 @@  enum edp_panel_type {
 enum edp_drrs_refresh_rate_type {
 	DRRS_HIGH_RR,
 	DRRS_LOW_RR,
+	DRRS_50HZ_RR,
+	DRRS_48HZ_RR,
 	DRRS_MAX_RR, /* RR count */
 };
 /**