From patchwork Thu Sep 6 20:54:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1417841 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 92E923FC71 for ; Thu, 6 Sep 2012 20:58:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6D33B9E793 for ; Thu, 6 Sep 2012 13:58:02 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from shiva.chad-versace.us (209-20-75-48.static.cloud-ips.com [209.20.75.48]) by gabe.freedesktop.org (Postfix) with ESMTP id 2A3AD9E829 for ; Thu, 6 Sep 2012 13:55:06 -0700 (PDT) Received: by shiva.chad-versace.us (Postfix, from userid 1005) id 6E043885D1; Thu, 6 Sep 2012 20:55:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on shiva.chad-versace.us X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED autolearn=unavailable version=3.3.2 Received: from stallone.nims.intel.com (unknown [192.102.209.254]) by shiva.chad-versace.us (Postfix) with ESMTPSA id 53E57885D0; Thu, 6 Sep 2012 20:54:54 +0000 (UTC) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Thu, 6 Sep 2012 13:54:08 -0700 Message-Id: <1346964850-2228-6-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.7.12 In-Reply-To: <1346964850-2228-1-git-send-email-ben@bwidawsk.net> References: <1346964850-2228-1-git-send-email-ben@bwidawsk.net> Cc: Daniel Vetter , Ben Widawsky , Jacob Pan , Arjan van de Ven Subject: [Intel-gfx] [PATCH 5/7] drm/i915: Add setters for min/max frequency X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Provide a standardized sysfs interface for setting min, and max frequencies. The code which reads the limits were lifted from the debugfs files. As a brief explanation, the limits are similar to the CPU p-states. We have 3 states: RP0 - ie. max frequency RP1 - ie. "local min" frequency RPn - seriously lowest frequency Initially Daniel asked me to clamp the writes to supported values, but in conforming to the way the cpufreq drivers seem to work, instead return -EINVAL (noticed by Jesse in discussion). The values can be used by userspace wishing to control the limits of the GPU (see the CC list for people who care). CC: Arjan van de Ven CC: Jacob Pan CC: Daniel Vetter CC: Jesse Barnes Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_sysfs.c | 78 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 6c7f905..5a5e610 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -238,6 +238,43 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute return snprintf(buf, PAGE_SIZE, "%d", ret); } +static ssize_t gt_max_freq_mhz_store(struct device *kdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); + struct drm_device *dev = minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val, rp_state_cap, hw_max; + ssize_t ret; + + ret = kstrtou32(buf, 0, &val); + if (ret) + return ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); + hw_max = (rp_state_cap & 0xff) * GT_FREQUENCY_MULTIPLIER; + + if (val > hw_max) + return -EINVAL; + + if (val < dev_priv->rps.min_delay) + val = dev_priv->rps.min_delay; + + if (dev_priv->rps.cur_delay > val) + gen6_set_rps(dev_priv->dev, val); + + dev_priv->rps.max_delay = val / GT_FREQUENCY_MULTIPLIER; + + mutex_unlock(&dev->struct_mutex); + + return count; +} + static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); @@ -255,9 +292,46 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute return snprintf(buf, PAGE_SIZE, "%d", ret); } +static ssize_t gt_min_freq_mhz_store(struct device *kdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); + struct drm_device *dev = minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val, rp_state_cap, hw_min; + ssize_t ret; + + ret = kstrtou32(buf, 0, &val); + if (ret) + return ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); + hw_min = ((rp_state_cap & 0xff0000) >> 16) * GT_FREQUENCY_MULTIPLIER; + + if (val < hw_min) + return -EINVAL; + + if (val > dev_priv->rps.max_delay) + val = dev_priv->rps.max_delay; + + if (dev_priv->rps.cur_delay < val) + gen6_set_rps(dev_priv->dev, val); + + dev_priv->rps.min_delay = val / GT_FREQUENCY_MULTIPLIER; + + mutex_unlock(&dev->struct_mutex); + + return count; +} + static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL); -static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, NULL); -static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, NULL); +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); static const struct attribute *gen6_attrs[] = { &dev_attr_gt_cur_freq_mhz.attr,