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