This interface allows enabling/disabling of RC6 feature. It allows to see immediately the RC6 power management savings and will allow to expose this through sysfs interface for powertop to leverage its functionality. Signed-off-by: Alexandra Yates <alexandra.yates@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.c | 5 ++-- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_sysfs.c | 42 ++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_display.c | 3 +- drivers/gpu/drm/i915/intel_drv.h | 5 ++-- drivers/gpu/drm/i915/intel_pm.c | 53 ++++++++++++++++++++++++++++++++++-- 6 files changed, 99 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 29b4e79..6ffbdfb 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -950,7 +950,7 @@ int i915_reset(struct drm_device *dev) * of re-init after reset. */ if (INTEL_INFO(dev)->gen > 5) - intel_enable_gt_powersave(dev); + intel_enable_gt_powersave(dev, false); return 0; } @@ -1600,7 +1600,8 @@ static int intel_runtime_resume(struct device *device) if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) intel_hpd_init(dev_priv); - intel_enable_gt_powersave(dev); + if (dev_priv->rps.sysfs_set != true) + intel_enable_gt_powersave(dev, dev_priv->rps.sysfs_set); enable_rpm_wakeref_asserts(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0f3a37f..bbe189f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1158,6 +1158,7 @@ struct intel_gen6_power_mgmt { * talking to hw - so only take it when talking to hw! */ struct mutex hw_lock; + bool sysfs_set; }; /* defined intel_pm.c */ diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 50d45ef..81aa534 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -71,7 +71,45 @@ static ssize_t show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_minor *dminor = dev_to_drm_minor(kdev); - return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6(dminor->dev)); + struct drm_device *dev = dminor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int enable_rc6; + + enable_rc6 = sanitize_rc6_option(dev, intel_enable_rc6(dminor->dev)); + return snprintf(buf, PAGE_SIZE, "%x\n", + (dev_priv->rps.enabled && enable_rc6)); +} + +static ssize_t +toggle_rc6(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; + u32 val; + ssize_t ret; + bool sysfs_set = true; + + ret = kstrtou32(buf, 0, &val); + if (ret) + return ret; + + switch (val) { + case 0: + ret = intel_disable_rc_powersave(dev, sysfs_set); + if (ret) + return ret; + break; + case 1: + ret = intel_enable_gt_powersave(dev, sysfs_set); + if (ret) + return ret; + break; + default: + return -EINVAL; + + } + return count; } static ssize_t @@ -228,7 +266,7 @@ toggle_psr(struct device *kdev, struct device_attribute *attr, static DEVICE_ATTR(fbc_enable, S_IRUGO | S_IWUSR, show_fbc, toggle_fbc); static DEVICE_ATTR(psr_enable, S_IRUGO | S_IWUSR, show_psr, toggle_psr); -static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL); +static DEVICE_ATTR(rc6_enable, S_IRUGO | S_IWUSR, show_rc6_mask, toggle_rc6); static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL); static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL); static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3d252b9..4a671e3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15256,7 +15256,8 @@ void intel_modeset_init_hw(struct drm_device *dev) dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; intel_init_clock_gating(dev); - intel_enable_gt_powersave(dev); + if (dev_priv->rps.sysfs_set != true) + intel_enable_gt_powersave(dev, dev_priv->rps.sysfs_set); } /* diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 93d09cc..d280847 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1586,8 +1586,9 @@ void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_teardown(void); void intel_init_gt_powersave(struct drm_device *dev); void intel_cleanup_gt_powersave(struct drm_device *dev); -void intel_enable_gt_powersave(struct drm_device *dev); -void intel_disable_gt_powersave(struct drm_device *dev); +int intel_enable_gt_powersave(struct drm_device *dev, bool sysfs_set); +int intel_disable_gt_powersave(struct drm_device *dev); +int intel_disable_rc_powersave(struct drm_device *dev, bool sysfs_set); void intel_suspend_gt_powersave(struct drm_device *dev); void intel_reset_gt_powersave(struct drm_device *dev); void gen6_update_ring_freq(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b8e395a..9ce9cda 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4587,6 +4587,13 @@ void intel_set_rps(struct drm_device *dev, u8 val) gen6_set_rps(dev, val); } +static void gen9_disable_rc(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_RC_CONTROL, 0); +} + static void gen9_disable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4595,6 +4602,13 @@ static void gen9_disable_rps(struct drm_device *dev) I915_WRITE(GEN9_PG_ENABLE, 0); } +static void gen6_disable_rc(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_RC_CONTROL, 0); +} + static void gen6_disable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6255,7 +6269,33 @@ void intel_suspend_gt_powersave(struct drm_device *dev) gen6_rps_idle(dev_priv); } -void intel_disable_gt_powersave(struct drm_device *dev) +int intel_disable_rc_powersave(struct drm_device *dev, bool sysfs_set) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (IS_IRONLAKE_M(dev)) { + ironlake_disable_drps(dev); + } else if (INTEL_INFO(dev)->gen >= 6) { + intel_suspend_gt_powersave(dev); + + mutex_lock(&dev_priv->rps.hw_lock); + if (INTEL_INFO(dev)->gen >= 9) + gen9_disable_rc(dev); + else if (IS_CHERRYVIEW(dev)) + cherryview_disable_rps(dev); + else if (IS_VALLEYVIEW(dev)) + valleyview_disable_rps(dev); + else + gen6_disable_rc(dev); + + dev_priv->rps.enabled = false; + dev_priv->rps.sysfs_set = sysfs_set; + mutex_unlock(&dev_priv->rps.hw_lock); + } + return 0; +} + +int intel_disable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6277,6 +6317,7 @@ void intel_disable_gt_powersave(struct drm_device *dev) dev_priv->rps.enabled = false; mutex_unlock(&dev_priv->rps.hw_lock); } + return 0; } static void intel_gen6_powersave_work(struct work_struct *work) @@ -6322,13 +6363,14 @@ static void intel_gen6_powersave_work(struct work_struct *work) intel_runtime_pm_put(dev_priv); } -void intel_enable_gt_powersave(struct drm_device *dev) +int intel_enable_gt_powersave(struct drm_device *dev, bool sysfs_set) { struct drm_i915_private *dev_priv = dev->dev_private; + int ret = 0; /* Powersaving is controlled by the host when inside a VM */ if (intel_vgpu_active(dev)) - return; + return -ENOTTY; if (IS_IRONLAKE_M(dev)) { ironlake_enable_drps(dev); @@ -6352,6 +6394,11 @@ void intel_enable_gt_powersave(struct drm_device *dev) round_jiffies_up_relative(HZ))) intel_runtime_pm_get_noresume(dev_priv); } + + mutex_lock(&dev_priv->rps.hw_lock); + dev_priv->rps.sysfs_set = sysfs_set; + mutex_unlock(&dev_priv->rps.hw_lock); + return ret; } void intel_reset_gt_powersave(struct drm_device *dev) -- 2.5.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx