xref: /openbmc/linux/drivers/gpu/drm/i915/i915_sysfs.c (revision 0136db586c028f71e7cc21cc183064ff0d5919c8)
1*0136db58SBen Widawsky /*
2*0136db58SBen Widawsky  * Copyright © 2012 Intel Corporation
3*0136db58SBen Widawsky  *
4*0136db58SBen Widawsky  * Permission is hereby granted, free of charge, to any person obtaining a
5*0136db58SBen Widawsky  * copy of this software and associated documentation files (the "Software"),
6*0136db58SBen Widawsky  * to deal in the Software without restriction, including without limitation
7*0136db58SBen Widawsky  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*0136db58SBen Widawsky  * and/or sell copies of the Software, and to permit persons to whom the
9*0136db58SBen Widawsky  * Software is furnished to do so, subject to the following conditions:
10*0136db58SBen Widawsky  *
11*0136db58SBen Widawsky  * The above copyright notice and this permission notice (including the next
12*0136db58SBen Widawsky  * paragraph) shall be included in all copies or substantial portions of the
13*0136db58SBen Widawsky  * Software.
14*0136db58SBen Widawsky  *
15*0136db58SBen Widawsky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*0136db58SBen Widawsky  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*0136db58SBen Widawsky  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*0136db58SBen Widawsky  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*0136db58SBen Widawsky  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*0136db58SBen Widawsky  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*0136db58SBen Widawsky  * IN THE SOFTWARE.
22*0136db58SBen Widawsky  *
23*0136db58SBen Widawsky  * Authors:
24*0136db58SBen Widawsky  *    Ben Widawsky <ben@bwidawsk.net>
25*0136db58SBen Widawsky  *
26*0136db58SBen Widawsky  */
27*0136db58SBen Widawsky 
28*0136db58SBen Widawsky #include <linux/device.h>
29*0136db58SBen Widawsky #include <linux/module.h>
30*0136db58SBen Widawsky #include <linux/stat.h>
31*0136db58SBen Widawsky #include <linux/sysfs.h>
32*0136db58SBen Widawsky #include "i915_drv.h"
33*0136db58SBen Widawsky 
34*0136db58SBen Widawsky static u32 calc_residency(struct drm_device *dev, const u32 reg)
35*0136db58SBen Widawsky {
36*0136db58SBen Widawsky 	struct drm_i915_private *dev_priv = dev->dev_private;
37*0136db58SBen Widawsky 	u64 raw_time; /* 32b value may overflow during fixed point math */
38*0136db58SBen Widawsky 
39*0136db58SBen Widawsky 	if (!intel_enable_rc6(dev))
40*0136db58SBen Widawsky 		return 0;
41*0136db58SBen Widawsky 
42*0136db58SBen Widawsky 	raw_time = I915_READ(reg) * 128ULL + 500;
43*0136db58SBen Widawsky 	return do_div(raw_time, 100000);
44*0136db58SBen Widawsky }
45*0136db58SBen Widawsky 
46*0136db58SBen Widawsky static ssize_t
47*0136db58SBen Widawsky show_rc6_mask(struct device *dev, struct device_attribute *attr, char *buf)
48*0136db58SBen Widawsky {
49*0136db58SBen Widawsky 	struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
50*0136db58SBen Widawsky 	return snprintf(buf, PAGE_SIZE, "%x", intel_enable_rc6(dminor->dev));
51*0136db58SBen Widawsky }
52*0136db58SBen Widawsky 
53*0136db58SBen Widawsky static ssize_t
54*0136db58SBen Widawsky show_rc6_ms(struct device *dev, struct device_attribute *attr, char *buf)
55*0136db58SBen Widawsky {
56*0136db58SBen Widawsky 	struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
57*0136db58SBen Widawsky 	u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6);
58*0136db58SBen Widawsky 	return snprintf(buf, PAGE_SIZE, "%u", rc6_residency);
59*0136db58SBen Widawsky }
60*0136db58SBen Widawsky 
61*0136db58SBen Widawsky static ssize_t
62*0136db58SBen Widawsky show_rc6p_ms(struct device *dev, struct device_attribute *attr, char *buf)
63*0136db58SBen Widawsky {
64*0136db58SBen Widawsky 	struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
65*0136db58SBen Widawsky 	u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
66*0136db58SBen Widawsky 	return snprintf(buf, PAGE_SIZE, "%u", rc6p_residency);
67*0136db58SBen Widawsky }
68*0136db58SBen Widawsky 
69*0136db58SBen Widawsky static ssize_t
70*0136db58SBen Widawsky show_rc6pp_ms(struct device *dev, struct device_attribute *attr, char *buf)
71*0136db58SBen Widawsky {
72*0136db58SBen Widawsky 	struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
73*0136db58SBen Widawsky 	u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
74*0136db58SBen Widawsky 	return snprintf(buf, PAGE_SIZE, "%u", rc6pp_residency);
75*0136db58SBen Widawsky }
76*0136db58SBen Widawsky 
77*0136db58SBen Widawsky static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
78*0136db58SBen Widawsky static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL);
79*0136db58SBen Widawsky static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL);
80*0136db58SBen Widawsky static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL);
81*0136db58SBen Widawsky 
82*0136db58SBen Widawsky static struct attribute *rc6_attrs[] = {
83*0136db58SBen Widawsky 	&dev_attr_rc6_enable.attr,
84*0136db58SBen Widawsky 	&dev_attr_rc6_residency_ms.attr,
85*0136db58SBen Widawsky 	&dev_attr_rc6p_residency_ms.attr,
86*0136db58SBen Widawsky 	&dev_attr_rc6pp_residency_ms.attr,
87*0136db58SBen Widawsky 	NULL
88*0136db58SBen Widawsky };
89*0136db58SBen Widawsky 
90*0136db58SBen Widawsky static struct attribute_group rc6_attr_group = {
91*0136db58SBen Widawsky 	.name = power_group_name,
92*0136db58SBen Widawsky 	.attrs =  rc6_attrs
93*0136db58SBen Widawsky };
94*0136db58SBen Widawsky 
95*0136db58SBen Widawsky void i915_setup_sysfs(struct drm_device *dev)
96*0136db58SBen Widawsky {
97*0136db58SBen Widawsky 	int ret;
98*0136db58SBen Widawsky 
99*0136db58SBen Widawsky 	/* ILK doesn't have any residency information */
100*0136db58SBen Widawsky 	if (INTEL_INFO(dev)->gen < 6)
101*0136db58SBen Widawsky 		return;
102*0136db58SBen Widawsky 
103*0136db58SBen Widawsky 	ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
104*0136db58SBen Widawsky 	if (ret)
105*0136db58SBen Widawsky 		DRM_ERROR("sysfs setup failed\n");
106*0136db58SBen Widawsky }
107*0136db58SBen Widawsky 
108*0136db58SBen Widawsky void i915_teardown_sysfs(struct drm_device *dev)
109*0136db58SBen Widawsky {
110*0136db58SBen Widawsky 	sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
111*0136db58SBen Widawsky }
112