[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