[Intel-gfx] [PATCH 17/31] drm/i915: Add sys PSR toggle interface.
Rodrigo Vivi
rodrigo.vivi at intel.com
Thu Nov 5 10:50:09 PST 2015
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 at intel.com>
---
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
More information about the Intel-gfx
mailing list