[PATCH 17/31] drm/i915: Add sys PSR toggle interface.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This interface allows an immediate enabling of PSR feature.
What allow us to see immediately the PSR savings and will
allow us to expose this through powertop interface.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx>
---
 drivers/gpu/drm/i915/i915_sysfs.c | 82 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h  |  4 +-
 drivers/gpu/drm/i915/intel_psr.c  | 19 +++++++--
 3 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 2d092c1..0f371c6 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -111,6 +111,81 @@ static struct attribute_group ips_attr_group = {
 	.attrs =  ips_attrs
 };
 
+static ssize_t
+psr_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = dminor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	ssize_t ret;
+
+	mutex_lock(&dev_priv->psr.lock);
+	ret = snprintf(buf, PAGE_SIZE, "%s\n", dev_priv->psr.enabled ?
+		       "enabled" : "disabled");
+	mutex_unlock(&dev_priv->psr.lock);
+
+	return ret;
+}
+
+
+static ssize_t
+psr_toggle(struct device *kdev, struct device_attribute *attr,
+	   const char *buf, size_t count)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = dminor->dev;
+	struct intel_connector *connector;
+	struct intel_encoder *encoder;
+	struct intel_crtc *crtc = NULL;
+	u32 val;
+	ssize_t ret;
+
+	ret = kstrtou32(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	for_each_intel_connector(dev, connector) {
+		if (!connector->base.encoder)
+			continue;
+		encoder = to_intel_encoder(connector->base.encoder);
+		crtc = to_intel_crtc(encoder->base.crtc);
+	}
+
+	if (!crtc)
+		return -ENODEV;
+
+	switch (val) {
+	case 0:
+		ret = intel_psr_disable(crtc);
+		if (ret)
+			return ret;
+		break;
+	case 1:
+		ret = intel_psr_enable(crtc);
+		if (ret)
+			return ret;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return count;
+
+
+}
+
+static DEVICE_ATTR(psr_enable, S_IRUGO | S_IWUSR, psr_show, psr_toggle);
+
+static struct attribute *psr_attrs[] = {
+	&dev_attr_psr_enable.attr,
+	NULL
+};
+
+static struct attribute_group psr_attr_group = {
+	.name = power_group_name,
+	.attrs =  psr_attrs
+};
+
 static u32 calc_residency(struct drm_device *dev, const u32 reg)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -667,6 +742,12 @@ void i915_setup_sysfs(struct drm_device *dev)
 		if (ret)
 			DRM_ERROR("IPS sysfs setup failed\n");
 	}
+	if (HAS_PSR(dev)) {
+		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
+					&psr_attr_group);
+		if (ret)
+			DRM_ERROR("PSR sysfs setup failed\n");
+	}
 	if (HAS_RC6(dev)) {
 		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
 					&rc6_attr_group);
@@ -724,6 +805,7 @@ void i915_teardown_sysfs(struct drm_device *dev)
 	device_remove_bin_file(dev->primary->kdev,  &dpf_attrs);
 #ifdef CONFIG_PM
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &ips_attr_group);
+	sysfs_unmerge_group(&dev->primary->kdev->kobj, &psr_attr_group);
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group);
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6p_attr_group);
 #endif
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bf5e77c..76e0805 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1408,8 +1408,8 @@ void intel_backlight_unregister(struct drm_device *dev);
 /* intel_psr.c */
 bool intel_psr_ready(struct intel_dp *intel_dp,
 		     struct intel_crtc_state *pipe_config);
-void intel_psr_enable(struct intel_crtc *intel_crtc);
-void intel_psr_disable(struct intel_crtc *intel_crtc);
+int intel_psr_enable(struct intel_crtc *intel_crtc);
+int intel_psr_disable(struct intel_crtc *intel_crtc);
 void intel_psr_invalidate(struct drm_device *dev,
 			  unsigned frontbuffer_bits);
 void intel_psr_flush(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index bcf2d9d..4ca682a 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -374,21 +374,26 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
  * @intel_crtc: Intel CRTC
  *
  * This function can only be called after the pipe is fully trained and enabled.
+ *
+ * Returns:
+ * 0 on success and -errno otherwise.
  */
-void intel_psr_enable(struct intel_crtc *intel_crtc)
+int intel_psr_enable(struct intel_crtc *intel_crtc)
 {
 	struct drm_crtc *crtc = &intel_crtc->base;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *intel_encoder;
 	struct intel_dp *intel_dp = NULL;
+	int ret = 0;
 
 	if (!intel_crtc->config->psr_ready)
-		return;
+		return -EINVAL;
 
 	mutex_lock(&dev_priv->psr.lock);
 	if (dev_priv->psr.enabled) {
 		DRM_DEBUG_KMS("PSR already in use\n");
+		ret = -EALREADY;
 		goto unlock;
 	}
 
@@ -399,6 +404,7 @@ void intel_psr_enable(struct intel_crtc *intel_crtc)
 
 	if (!intel_dp) {
 		DRM_DEBUG_KMS("No eDP found\n");
+		ret = -ENOTTY;
 		goto unlock;
 	}
 
@@ -443,6 +449,7 @@ void intel_psr_enable(struct intel_crtc *intel_crtc)
 	dev_priv->psr.enabled = intel_dp;
 unlock:
 	mutex_unlock(&dev_priv->psr.lock);
+	return ret;
 }
 
 static void vlv_psr_disable(struct intel_dp *intel_dp)
@@ -498,8 +505,11 @@ static void hsw_psr_disable(struct intel_dp *intel_dp)
  * @intel_crtc: Intel CRTC
  *
  * This function needs to be called before disabling pipe.
+ *
+ * Returns:
+ * 0 on success and -errno otherwise.
  */
-void intel_psr_disable(struct intel_crtc *intel_crtc)
+int intel_psr_disable(struct intel_crtc *intel_crtc)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -507,7 +517,7 @@ void intel_psr_disable(struct intel_crtc *intel_crtc)
 	mutex_lock(&dev_priv->psr.lock);
 	if (!dev_priv->psr.enabled) {
 		mutex_unlock(&dev_priv->psr.lock);
-		return;
+		return -EALREADY;
 	}
 
 	if (HAS_DDI(dev))
@@ -519,6 +529,7 @@ void intel_psr_disable(struct intel_crtc *intel_crtc)
 	mutex_unlock(&dev_priv->psr.lock);
 
 	cancel_delayed_work_sync(&dev_priv->psr.work);
+	return 0;
 }
 
 static void intel_psr_work(struct work_struct *work)
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux