[Intel-gfx] [PATCH 06/10] drm/i915: Define a separate variable and control for RPS waitboost frequency
Mika Kuoppala
mika.kuoppala at linux.intel.com
Mon Jul 11 11:39:19 UTC 2016
Chris Wilson <chris at chris-wilson.co.uk> writes:
> To allow the user finer control over waitboosting, allow them to set the
> frequency we request for the boost. This also them allows to effectively
> disable the boosting by setting the boost request to a low frequency.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 2 ++
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/i915_irq.c | 9 +++++----
> drivers/gpu/drm/i915/i915_sysfs.c | 38 +++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_pm.c | 5 ++++-
> 5 files changed, 50 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 844fea795bae..d1ff4cb9b90e 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1381,6 +1381,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
> intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
> seq_printf(m, "Min freq: %d MHz\n",
> intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
> + seq_printf(m, "Boost freq: %d MHz\n",
> + intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
> seq_printf(m, "Max freq: %d MHz\n",
> intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
> seq_printf(m,
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4478cc852489..bb59bc637f7b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1170,6 +1170,7 @@ struct intel_gen6_power_mgmt {
> u8 max_freq_softlimit; /* Max frequency permitted by the driver */
> u8 max_freq; /* Maximum frequency, RP0 if not overclocking */
> u8 min_freq; /* AKA RPn. Minimum frequency */
> + u8 boost_freq; /* Frequency to request when wait boosting */
> u8 idle_freq; /* Frequency to request when we are idle */
> u8 efficient_freq; /* AKA RPe. Pre-determined balanced frequency */
> u8 rp1_freq; /* "less than" RP0 power/freqency */
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 1c2aec392412..c8ed36765301 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1105,9 +1105,10 @@ static void gen6_pm_rps_work(struct work_struct *work)
> new_delay = dev_priv->rps.cur_freq;
> min = dev_priv->rps.min_freq_softlimit;
> max = dev_priv->rps.max_freq_softlimit;
> -
> - if (client_boost) {
> - new_delay = dev_priv->rps.max_freq_softlimit;
> + if (client_boost || any_waiters(dev_priv))
> + max = dev_priv->rps.max_freq;
> + if (client_boost && new_delay < dev_priv->rps.boost_freq) {
> + new_delay = dev_priv->rps.boost_freq;
What should be the rules for boost_freq? With this change it can
be over max_freq_softlimit and thus will break pm_rps.
-Mika
> adj = 0;
> } else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
> if (adj > 0)
> @@ -1122,7 +1123,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
> new_delay = dev_priv->rps.efficient_freq;
> adj = 0;
> }
> - } else if (any_waiters(dev_priv)) {
> + } else if (client_boost || any_waiters(dev_priv)) {
> adj = 0;
> } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
> if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq)
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index d61829e54f93..8c045ff47f0e 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.c
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -318,6 +318,41 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
> return snprintf(buf, PAGE_SIZE, "%d\n", ret);
> }
>
> +static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
> +{
> + struct drm_minor *minor = dev_to_drm_minor(kdev);
> + struct drm_i915_private *dev_priv = to_i915(minor->dev);
> +
> + return snprintf(buf, PAGE_SIZE, "%d\n",
> + intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
> +}
> +
> +static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct drm_minor *minor = dev_to_drm_minor(kdev);
> + struct drm_device *dev = minor->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + u32 val;
> + ssize_t ret;
> +
> + ret = kstrtou32(buf, 0, &val);
> + if (ret)
> + return ret;
> +
> + /* Validate against (static) hardware limits */
> + val = intel_freq_opcode(dev_priv, val);
> + if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq)
> + return -EINVAL;
> +
> + mutex_lock(&dev_priv->rps.hw_lock);
> + dev_priv->rps.boost_freq = val;
> + mutex_unlock(&dev_priv->rps.hw_lock);
> +
> + return count;
> +}
> +
> static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
> struct device_attribute *attr, char *buf)
> {
> @@ -465,6 +500,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
>
> static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
> static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
> +static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
> static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
> static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
>
> @@ -498,6 +534,7 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
> static const struct attribute *gen6_attrs[] = {
> &dev_attr_gt_act_freq_mhz.attr,
> &dev_attr_gt_cur_freq_mhz.attr,
> + &dev_attr_gt_boost_freq_mhz.attr,
> &dev_attr_gt_max_freq_mhz.attr,
> &dev_attr_gt_min_freq_mhz.attr,
> &dev_attr_gt_RP0_freq_mhz.attr,
> @@ -509,6 +546,7 @@ static const struct attribute *gen6_attrs[] = {
> static const struct attribute *vlv_attrs[] = {
> &dev_attr_gt_act_freq_mhz.attr,
> &dev_attr_gt_cur_freq_mhz.attr,
> + &dev_attr_gt_boost_freq_mhz.attr,
> &dev_attr_gt_max_freq_mhz.attr,
> &dev_attr_gt_min_freq_mhz.attr,
> &dev_attr_gt_RP0_freq_mhz.attr,
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 24b23a51c56b..aab1e0b5d2eb 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4911,7 +4911,7 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv,
> */
> if (!(dev_priv->gt.awake &&
> dev_priv->rps.enabled &&
> - dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit))
> + dev_priv->rps.cur_freq < dev_priv->rps.boost_freq))
> return;
>
> /* Force a RPS boost (and don't count it against the client) if
> @@ -6532,6 +6532,9 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
> }
> }
>
> + /* Finally allow us to boost to max by default */
> + dev_priv->rps.boost_freq = dev_priv->rps.max_freq;
> +
> mutex_unlock(&dev_priv->rps.hw_lock);
> }
>
> --
> 2.8.1
More information about the Intel-gfx
mailing list