diff mbox

[RFC,08/18] drm/i915: VLV eDP DRRS methods

Message ID 1435326722-24633-9-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
VLV related ePD drrs functions are implemented and registered
with generic eDP drrs module.

This will provide the platform specific services to generic ePD drrs
stack, like program the pll registers for DRRS functionality.

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

Patch

diff --git a/drivers/gpu/drm/i915/intel_edp_drrs.c b/drivers/gpu/drm/i915/intel_edp_drrs.c
index 606271b..8968e4c 100644
--- a/drivers/gpu/drm/i915/intel_edp_drrs.c
+++ b/drivers/gpu/drm/i915/intel_edp_drrs.c
@@ -20,6 +20,71 @@ 
 
 #include "i915_drv.h"
 
+/*
+ * VLV eDP DRRS Support
+ */
+
+static int vlv_edp_drrs_init(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+
+	if (dev_priv->psr.enabled) {
+		DRM_ERROR("eDP DRRS is disabled as PSR is enabled already\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void vlv_edp_drrs_exit(struct intel_encoder *encoder)
+{
+}
+
+static int vlv_edp_set_drrs_state(struct intel_encoder *encoder,
+				enum drrs_refresh_rate_type target_rr_type)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	u32 reg, val;
+
+	if (!crtc)
+		return -EINVAL;
+
+	reg = PIPECONF(crtc->config->cpu_transcoder);
+	val = I915_READ(reg);
+
+	switch (target_rr_type) {
+	case DRRS_HIGH_RR:
+		if (IS_VALLEYVIEW(dev))
+			val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+		break;
+	case DRRS_LOW_RR:
+		if (IS_VALLEYVIEW(dev))
+			val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+		break;
+	default:
+		DRM_ERROR("invalid refresh rate type\n");
+		return -EINVAL;
+	}
+
+	I915_WRITE(reg, val);
+	return 0;
+}
+
+struct edp_drrs_platform_ops vlv_edp_drrs_ops = {
+	.init = vlv_edp_drrs_init,
+	.exit = vlv_edp_drrs_exit,
+	.set_drrs_state = vlv_edp_set_drrs_state,
+};
+
+struct edp_drrs_platform_ops *get_vlv_edp_drrs_ops(void)
+{
+	return &vlv_edp_drrs_ops;
+}
+
+/*
+ * Generic eDP DRRS implementation
+ */
 void intel_edp_set_drrs_state(struct i915_drrs *drrs)
 {
 	struct intel_encoder *intel_encoder = drrs->connector->encoder;
@@ -37,6 +102,13 @@  int intel_edp_drrs_init(struct i915_drrs *drrs,
 	struct drm_display_mode *downclock_mode;
 	int ret = -EINVAL;
 
+	if (IS_VALLEYVIEW(intel_encoder->base.dev))
+
+		/* VLV and CHV */
+		intel_dp->drrs_ops = get_vlv_edp_drrs_ops();
+	else
+		intel_dp->drrs_ops = NULL;
+
 	if (!intel_dp->drrs_ops ||
 			!intel_dp->drrs_ops->set_drrs_state) {
 		DRM_ERROR("Required platform ops are NULL\n");