[Intel-gfx] [PATCH 3/3] drm/i915: rc6 in sysfs
Ben Widawsky
ben at bwidawsk.net
Sun Mar 25 04:14:37 CEST 2012
I sent stale patches, but this is the only one with a big effect. See
inline for what's fixed, and feel free to review the rest.
On Sat, 24 Mar 2012 19:09:46 -0700
Ben Widawsky <ben at bwidawsk.net> wrote:
> Merge rc6 information into the power group for our device. Until now
> the i915 driver has not had any sysfs entries (aside from the
> connector stuff enabled by libdrm). Since it seems like we're likely
> to have more in the future I created a new file for sysfs stubs, as
> well as the rc6 sysfs functions which don't really belong elsewhere
> (perhaps i915_suspend, but most of the stuff is in intel_display,c).
>
> displays #ms GPU has been in rc6 since boot:
> cat /sys/class/drm/card0/power/rc6
>
> displays #ms GPU has been in deep rc6 since boot:
> cat /sys/class/drm/card0/power/rc6p
>
> displays #ms GPU has been in deepest rc6 since boot:
> cat /sys/class/drm/card0/power/rc6pp
>
> Important note: I've seen on SNB that even when RC6 is *not* enabled
> the rc6 register seems to have a random value in it. I cannot explain
> a reason for this. Those writing tools that utilize this value need
> to be careful and probably want to scrutinize the value very
> carefully.
>
> Please see intel-gpu-tools patches for sample code.
>
> CC: Arjan van de Ven <arjan at linux.intel.com>
> Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
> ---
> drivers/gpu/drm/i915/Makefile | 1 +
> drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
> drivers/gpu/drm/i915/i915_dma.c | 4 ++
> drivers/gpu/drm/i915/i915_drv.h | 4 ++
> drivers/gpu/drm/i915/i915_sysfs.c | 106
> +++++++++++++++++++++++++++++++++++ 5 files changed, 116
> insertions(+), 1 deletion(-) create mode 100644
> drivers/gpu/drm/i915/i915_sysfs.c
>
> diff --git a/drivers/gpu/drm/i915/Makefile
> b/drivers/gpu/drm/i915/Makefile index ce7fc77..f801330 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -12,6 +12,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
> i915_gem_execbuffer.o \
> i915_gem_gtt.o \
> i915_gem_tiling.o \
> + i915_sysfs.o \
> i915_trace_points.o \
> intel_display.o \
> intel_crt.o \
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> b/drivers/gpu/drm/i915/i915_debugfs.c index 72457ff..4257151 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1134,9 +1134,9 @@ static int gen6_drpc_info(struct seq_file *m)
> seq_printf(m, "Core Power Down: %s\n",
> yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK));
>
> + /* Not exactly sure what this is */
> seq_printf(m, "RC6 \"Locked to RPn\" residency since boot:
> %d\n", I915_READ(GEN6_GT_GFX_RC6_LOCKED));
> - /* Not exactly sure what this is */
> seq_printf(m, "RC6 residency since boot: %d\n",
> I915_READ(GEN6_GT_GFX_RC6));
> seq_printf(m, "RC6+ residency since boot: %d\n",
This hunk should be rebased on patch 1... my bad. I'll fix after
waiting on some review.
> diff --git a/drivers/gpu/drm/i915/i915_dma.c
> b/drivers/gpu/drm/i915/i915_dma.c index fdff009..64dfbb8 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -2113,6 +2113,8 @@ int i915_driver_load(struct drm_device *dev,
> unsigned long flags) }
> }
>
> + i915_setup_sysfs(dev);
> +
> /* Must be done after probing outputs */
> intel_opregion_init(dev);
> acpi_video_register();
> @@ -2164,6 +2166,8 @@ int i915_driver_unload(struct drm_device *dev)
> i915_mch_dev = NULL;
> spin_unlock(&mchdev_lock);
>
> + i915_teardown_sysfs(dev);
> +
> if (dev_priv->mm.inactive_shrinker.shrink)
> unregister_shrinker(&dev_priv->mm.inactive_shrinker);
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h index 22ab4db..e267774 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1365,6 +1365,10 @@ extern int i915_restore_state(struct
> drm_device *dev); extern int i915_save_state(struct drm_device *dev);
> extern int i915_restore_state(struct drm_device *dev);
>
> +/* i915_sysfs.c */
> +void i915_setup_sysfs(struct drm_device *dev_priv);
> +void i915_teardown_sysfs(struct drm_device *dev_priv);
> +
> /* intel_i2c.c */
> extern int intel_setup_gmbus(struct drm_device *dev);
> extern void intel_teardown_gmbus(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c
> b/drivers/gpu/drm/i915/i915_sysfs.c new file mode 100644
> index 0000000..a18a955f
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -0,0 +1,106 @@
> +/*
> + * Copyright © 2012 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person
> obtaining a
> + * copy of this software and associated documentation files (the
> "Software"),
> + * to deal in the Software without restriction, including without
> limitation
> + * the rights to use, copy, modify, merge, publish, distribute,
> sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom
> the
> + * Software is furnished to do so, subject to the following
> conditions:
> + *
> + * The above copyright notice and this permission notice (including
> the next
> + * paragraph) shall be included in all copies or substantial
> portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
> EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
> OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + * Ben Widawsky <ben at bwidawsk.net>
> + *
> + */
> +
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/stat.h>
> +#include <linux/sysfs.h>
> +#include "i915_drv.h"
> +
> +static u32 calc_residency(struct drm_device *dev, const u32 reg)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + u64 raw_time;
> + u32 residency;
> +
> + if (!intel_enable_rc6(dev))
> + return 0;
> +
> + raw_time = I915_READ(reg) * 128ULL;
> + residency = DIV_ROUND_CLOSEST(raw_time, 1000) / 100;
> + return residency;
> +}
> +
> +static ssize_t
> +show_rc6pp_ms(struct device *dev, struct device_attribute *attr,
> char *buf) +{
> + struct drm_minor *dminor = container_of(dev, struct
> drm_minor, kdev);
> + u32 rc6pp_residency = calc_residency(dminor->dev,
> GEN6_GT_GFX_RC6pp);
> + return snprintf(buf, PAGE_SIZE, "%u", rc6pp_residency);
> +}
> +
> +static ssize_t
> +show_rc6_ms(struct device *dev, struct device_attribute *attr, char
> *buf) +{
> + struct drm_minor *dminor = container_of(dev, struct
> drm_minor, kdev);
> + struct drm_i915_private *dev_priv = dminor->dev->dev_private;
> + /* 32b value may overflow during fixed point math */
> + u64 time = (I915_READ(GEN6_GT_GFX_RC6) * 128);
> + u32 rc6_residency = DIV_ROUND_CLOSEST(time, 1000) / 100;
> + return snprintf(buf, PAGE_SIZE, "%u", rc6_residency);
> +}
> +
> +static ssize_t
> +show_rc6p_ms(struct device *dev, struct device_attribute *attr, char
> *buf) +{
> + struct drm_minor *dminor = container_of(dev, struct
> drm_minor, kdev);
> + struct drm_i915_private *dev_priv = dminor->dev->dev_private;
> + /* 32b value may overflow during fixed point math */
> + u64 time = (I915_READ(GEN6_GT_GFX_RC6p) * 128);
> + u32 rc6p_residency = DIV_ROUND_CLOSEST(time, 1000) / 100;
> + return snprintf(buf, PAGE_SIZE, "%u", rc6p_residency);
> +}
These all use calc_residenc() in the newer patch. Again will wait on
some review before fixing.
> +
> +static DEVICE_ATTR(rc6, S_IRUGO, show_rc6_ms, NULL);
> +static DEVICE_ATTR(rc6p, S_IRUGO, show_rc6p_ms, NULL);
> +static DEVICE_ATTR(rc6pp, S_IRUGO, show_rc6pp_ms, NULL);
> +
> +static struct attribute *rc6_attrs[] = {
> + &dev_attr_rc6.attr,
> + &dev_attr_rc6p.attr,
> + &dev_attr_rc6pp.attr,
> + NULL
> +};
> +
> +static struct attribute_group rc6_attr_group = {
> + .name = power_group_name,
> + .attrs = rc6_attrs
> +};
> +
> +void i915_setup_sysfs(struct drm_device *dev)
> +{
> + int ret;
> +
> + ret = sysfs_merge_group(&dev->primary->kdev.kobj,
> &rc6_attr_group);
> + if (ret)
> + DRM_ERROR("sysfs setup failed\n");
> +}
> +
> +void i915_teardown_sysfs(struct drm_device *dev)
> +{
> + sysfs_remove_group(&dev->primary->kdev.kobj,
> &rc6_attr_group); +}
More information about the Intel-gfx
mailing list